JAVA JVM的内存的堆和栈分别用途是什么呢?
先了解一JVM的内存分布,大体见下图所示:
程序计数器: 是一块较小的内存空间,它可以看做当前线程所执行的字节码的行号指示器,主要作用用来选择执行指令
JAVA 虚拟机栈: 于程序计算器一样也是线程私有的,它的生命周期与线程相同,它里面有局部变量表存放编译期可知的各种基本数据类型
本地方法栈: 本地方法栈为虚拟机使用到的NAtive方法服务
Java堆: 是虚拟机所管理的内存中最大的一块,是所有线程共享的一块内存区域;在虚拟机启动的时候创建;此内存区域的唯一目的就是存放对象实例,几乎所有的对象实例都在这里分配内存;Java堆也是垃圾收集管理的主要区域
方法区: 与Java堆一样,是各个线程共享的内存区域,它用于存储被虚拟机加载的类信息,常量,静态变量,及编译器编译后的代码等数据
二:堆中对象的定位
程序通过栈中对象的引用来操作堆中的对象;Java只定义了一个reference的引用,并没有给出这个引用经过何种方式去定位和访问堆中的对象;目前主流 的方式有两种:
1:句柄
使用句柄的时候,会在堆中创建一个句柄池,句柄池中保存着对象的实例数据指针、对象类型数据指针;
然后 栈中 refercence 引用保存着对象句柄池的地址;如下图所示:
2:直接指针
栈中的refernce存放直接是堆中对象的地址:
两种方式的优缺点:
句柄方式:当对象移动(或被垃圾回收的时候);只需要改变句柄中实例数据指针;refernce不需要变化
直接指针:速度快,节省时间开销