关于 Java 堆栈

来源:互联网 发布:c语言 编辑:程序博客网 时间:2024/06/10 10:35

最近 学习java,网上看到很多文章 关于 java 堆栈的解释,阅读量很大,转载超多, 但错的离谱,可能会误导很多新手,这里对其简单解释,希望能给新手解惑, 如有不妥之处,欢迎指正,保证及时改正 ^_^


原文引用

>>>>>>>>>>>>>>

JAVA 堆栈
栈与堆都是Java用来在Ram中存放数据的地方。与C++不同,Java自动管理栈和堆,程序员不能直接地设置栈或堆(A)
  Java的堆是一个运行时数据区,类的(对象从中分配空间。这些对象通过new、newarray、anewarray和multianewarray等指令建立,它们不需要程序代码来显式的释放。堆是由垃圾回收来负责的,堆的优势是可以动态地分配内存大小,生存期也不必事先告诉编译器,因为它是在运行时动态分配内存的,Java的垃圾收集器会自动收走这些不再使用的数据。但缺点是,由于要在运行时动态分配内存,存取速度较慢。 
  栈的优势是,存取速度比堆要快,仅次于寄存器,栈数据可以共享。但缺点是,存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。栈中主要存放一些基本类型的变量(,int, short, long, byte, float, double, boolean, char)和对象句柄。 
  栈有一个很重要的特殊性,就是存在栈中的数据可以共享(B)假设我们同时定义: 
  int a = 3; 
  int b = 3; 
  编译器先处理int a = 3;首先它会在栈中创建一个变量为a的引用,然后查找栈中是否有3这个值,如果没找到,就将3存放进来,然后将a指向3。接着处理int b = 3;在创建完b的引用变量后,因为在栈中已经有3这个值,便将b直接指向3。这样,就出现了a与b同时均指向3的情况。这时,如果再令a=4;那么编译器会重新搜索栈中是否有4值,如果没有,则将4存放进来,并令a指向4;如果已经有了,则直接将a指向这个地址。因此a值的改变不会影响到b的值。要注意这种数据的共享与两个对象的引用同时指向一个对象的这种共享是不同的,因为这种情况a的修改并不会影响到b, 它是由编译器完成的,它有利于节省空间。而一个对象引用变量修改了这个对象的内部状态,会影响到另一个对象引用变量 
----------------------------------------------------------------------------------------------
另外还有一个疑问:(C)
int [] arr={1,2,3,4}
即没有用new 显示生成的原始类型数组是存放在哪的
是存放在堆还是栈里。
在c++ 里肯定是在栈里(C++ 在堆里生成的一定要手动delete 掉自己回收的,而int a[]={1,3}我们不需手动回收)

<<<<<<<<<<<<<<<


这里不考虑 栈中对象等新特性,通常 一个 程序的运行,就是函数的调用过程,打印栈信息,也会看到相关的调用过程

基础不牢固的可以参考 c程序运行时数据结构


以下 分别对 (A)(B)(C) 三处进行解释

(A) 与C++不同,Java自动管理栈和堆,程序员不能直接地设置栈或堆

一般来说 程序 运行时数据结构 包括 Stack (栈 ) 和 Heap (堆), 函数调用均发生在 Stack 中,动态分配的内存 通常 会在 Heap 中进行。

C/C++ 和 Java 的 栈空间 均由程序自动管理,C/C++ 中的 堆 由程序员手动管理(malloc/free  new/delete), 当然也可以使用智能指针;Java 堆空间由 gc 进行统一管理,无需程序员手动释放。


(B)栈有一个很重要的特殊性,就是存在栈中的数据可以共享

结论:对于基本类型,C/C++/Java 都是直接存储数值的。

文中举例 int  a = 3; int b = 3; 编译器先处理。。。 Stack, Heap 都是 运行时数据结构,跟编译器已经没有关系了

假设去掉 编译器三个字, 文章最终想阐述的还是 栈空间存在数据共享, 首先 数据共享的目的是什么? 无非两个:1)节省空间;2)提高效率

以 32bit 机器考虑, 引用 , 整形 都是 4 个字节



无论从 空间利用率,还是 数据获取效率 角度看,文中的 栈空间数据共享 均没有什么优势

关于 linux 栈空间 可以参考  Linux虚拟地址空间布局以及进程栈和线程栈总结 


(C)另外还有一个疑问

int[] arr = {1,2,3,4};

C/C++ 中会 将其直接 分配到 栈 中;

Java 会将 {1,2,3,4} 分配在 堆 中,栈中 引用变量 arr 指向 堆中的实际数据,可以打印 hashCode 来验证

原创粉丝点击