整体架构
当一个java类文件被jvm装载进来,就需要创建对象,涉及到内存管理了。先来看看jvm内部的体系结构
对汇编有一定了解的同学都明白这个概念。我们可以简单把它看做是当前线程所执行的字节码的行号。有什么用呢。当执行完一条指令的时候,需要跳转到下一条指令,就得靠它了
java虚拟机栈是线程私有的,跟线程的生命周期相同。描述的是一个java方法执行的内存模型:当一个方法被执行的时候,就会创建一个栈帧(stack frame)用于存储局部变量列表、操作数栈、动态链接(即一些类或者方法的引用)、方法出口信息等。一个方法被调用到完成的过程,就是一个栈帧在jvm栈入帧到出帧的过程
Java堆这个是我们最熟悉的了,所有对象的创建都在这个区域。垃圾回收的重点区域也在这一款。这个区域我们可以再细分一下:新生代(Eden、From Survivor 和 To Survivor)和老年代。对象最早是分配在Eden区域的,当执行了一次min gc时,就会将该对象转移到其中一个Survivor。当对象存活一定时间后,可能被移到老年代。当老年代内存不足时,会引发Full GC。这就是大概的垃圾回收过程。详细的过程,我会在之后的blog中介绍
本地方法栈顾名思义,本地方法是跟调用本地方法相关的
方法区存储一些公共信息:类信息、常量、静态变量,即时编译后的代码
对象的访问句柄式。堆中会划分出一块内存作为句柄池,对象的引用其实是对象的句柄地址。通过它找到了句柄,句柄包括了对象实例数据(堆中)和类型数据(属于方法区)的具体地址。好处是对象的移动改变指针就行,对象的引用不需要改变
直接指针访问。对象就包括类型数据(属于方法区)的地址和实例数据。所以通过对象的引用就直接在java堆中找到了对象。好处是速度更快,跟句柄式的访问相比,少了一次指针定位的开销。Sun hosport就是采用这种方式的
参考资料1.深入java虚拟机
2.深入理解java虚拟机