深入理解Java堆栈

栈(stack)与堆(heap)

栈的优势是,存取速度比堆要快,仅次于直接位于CPU中的寄存器。但缺点是,存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。另外,栈数据可以共享。

堆的优势是可以动态地分配内存大小,生存期也不必事先告诉编译器,Java的垃圾收集器会自动收走这些不再使用的数据。但缺点是,由于要 在运行时动态分配内存,存取速度较慢。

怎样理解栈和堆?栈可以理解为内存中一片连续的区域,而堆可以理解为内存中一片分散的区域。可以说,栈是用来运行程序的区域,当在栈里应用一个值的时候,这个值就会指向堆中的一个位置

JVM在启动时,会开启虚拟机自身的线程,例如垃圾回收线程,还有java程序的线程,创建的线程名,同时创建对象和变量,这些都会放在JVM的中,而线程对象字符串,new的对象,变量,都会放在中;最后,变量的值,则会放在方法中,方法区和堆都是共享的,通过以上的叙述,就可以看出一些JVM的运行机制。

String b=new String(“test”);

我现在new了一个对象b这个对象名放在栈中,b这个对象值(对象字符串)放在堆中,"test"就会放到方法区中,这样的分工机制有效提升了程序运行的速度。

由此可见,堆是java应用程序最密切的内存空间。可以说所有的对象都存在堆中。而且堆的管理是自动化的,通过GC回收机制,垃圾对象会自动清理,不需要显式释放。

int a = 3; 
int b = 3; 

编译器先处理int a = 3;首先它会在栈中创建一个变量为a的引用,然后查找有没有字面值为3的地址,没找到,就开辟一个存放3这个字面值的地址,然后将a指向3的地址。接着处 理int b = 3;在创建完b的引用变量后,由于在栈中已经有3这个字面值,便将b直接指向3的地址。这样,就出现了a与b同时均指向3的情况。

int[] x=new int[3];
x[0]=20

以上程序执行步骤

  • 第1步——执行int[] x=new int[3];
      隐藏以下几分支
      JVM执行main()函数,在栈内存中开辟一个空间,存放x变量(x变量是局部变量)
      同时,在堆内存中也开辟一个空间,存放new int[3]数组,堆内存会自动内存首地址值,如0x0045
      数组在栈内存中的地址值,会附给x,这样x也有地址值。所以,x就指向(引用)了这个数组。此时,所有元素均未附值,但都有默认初始化值0。

  • 第2步——执行x[0]=20

    ​ 即在堆内存中将20附给[0]这个数组元素。这样,数组的三个元素值分别为20,0,0

    img

猜你喜欢

转载自blog.csdn.net/qq_41916173/article/details/88888648