java堆栈
java面试过程中经常会被问到关于堆栈的问题,这里我稍微总结一下,供大家参考一下。
java的内存分为堆内存和栈内存
栈内存是指程序进入一个方法时,会为这个方法单独分配一块私属存储空间,用于存储这个方法内部的局部变量,当这个方法结束时,分配给这个方法的栈会释放,这个栈中的变量也将随之释放。
堆是与栈作用不同的内存,一般用于存放不放在当前方法栈中的那些数据,例如,使用new创建的对象都放在堆里,所以,它不会随方法的结束而消失。方法中的局部变量使用final修饰后,放在堆中,而不是栈中。
从JVM认识堆栈
Stack(栈)是JVM的内存指令区。Stack管理很简单,push一 定长度字节的数据或者指令,Stack指针压栈相应的字节位移;pop一定字节长度数据或者指令,Stack指针弹栈。并且每次操作的数据或者指令字节长度是已知的。所以Java 基本数据类型,Java 指令代码,常量都保存在Stack中。
Heap(堆)是JVM的内存数据区。Heap 的管理很复杂,每次分配不定长的内存空间,专门用来保存对象的实例。
JVM空间分配
heap是堆:1、手动申请和释放空间2、大自由区
stack是栈:1、自动分配和释放2、空间有限
例:在Java中,若只是声明一个对象,则先在栈内存中为其分配地址空间,若再new一下,实例化它,则在堆内存中为其分配地址。
Object a=null;只在栈中分配内存。
new Object();在堆中分配空间。
Object b =new Object();在栈中分配空间,指向堆中的地址。
内存中堆栈的关系
Heap是 Stack的一个子集。
Stack存取速度仅次于寄存器,存储效率比heap高,可共享存储数据,但是其中数据的大小和生存期必须在运行前确定。
Heap是运行时可动态分配的数据区,从速度看比Stack慢,Heap里面的数据不共享,大小和生存期都可以在运行时再确定。
new关键字 是运行时在Heap里面创建对象,每new一次都一定会创建新对象,因为堆数据不共享。
回收上区别
Stack的内存管理是顺序分配的,而且定长,不存在内存回收问题
Heap 则是随机分配内存,不定长度,存在内存分配和回收的问题
在JVM中另有一个GC进程,定期扫描Heap ,它根据Stack中保存的4字节对象地址扫描Heap ,定位Heap 中这些对象,进行一些优化(例如合并空闲内存块什么的),并且假设Heap 中没有扫描到的区域都是空闲的,统统refresh(实际上是把Stack中丢失了对象地址的无用对象清除了),这就是垃圾收集的