JVM内存模型
JVM内存模型划分

程序计数器(线程私有):
是当前线程锁执行字节码的行号治时期,每条线程都有一个独立的程序计数器,这类内存也称为“线程私有”的内存。正在执行java方法的话,计数器记录的是虚拟机字节码指令的地址(当前指令的地址)。如果是Natice方法,则为空。
场景:多线程抢占CPU时间片,线程A执行到某一行代码,时间片被线程B抢占,当线程A重新获取时间片时,可以从程序计数器获取行号,继续执行。
java 虚拟机栈
线程私有的。
每个方法在执行的时候也会创建一个栈帧,存储了局部变量,操作数,动态链接,方法返回地址。
每个方法从调用到执行完毕,对应一个栈帧在虚拟机栈中的入栈和出栈。
通常所说的栈,一般是指在虚拟机栈中的局部变量部分。
局部变量所需内存在编译期间完成分配,
如果线程请求的栈深度大于虚拟机所允许的深度,则StackOverflowError。
如果虚拟机栈可以动态扩展,扩展到无法申请足够的内存,则OutOfMemoryError。
本地方法栈(线程私有)
一般我们在Java中看到native关键字修饰的方法,即为本地方法。
和虚拟机栈类似,主要为虚拟机使用到的Native方法服务。也会抛出StackOverflowError和OutOfMemoryError。
Java堆(线程共享)
被所有线程共享的一块内存区域,在虚拟机启动的时候创建,用于存放对象实例。
对可以按照可扩展来实现(通过-Xmx 和-Xms 来控制)
当队中没有内存可分配给实例,也无法再扩展时,则抛出OutOfMemoryError异常。
方法区(线程共享)
被所有方法线程共享的一块内存区域。
用于存储已经被虚拟机加载的类信息,常量,静态变量等。
这个区域的内存回收目标主要针对常量池的回收和堆类型的卸载。
Java堆专项
老年代:2/3的堆空间
年轻代:1/3的堆空间
eden区:8/10 的年轻代
survivor0: 1/10 的年轻代
survivor1:1/10的年轻代
- 年轻代
- Eden:对象初始化后,存放位置
- Survivor区:
- Survivor0
- Survivor1
- 老年代:年代达到15或者静态对象
分代年龄:每进行一次minor gc 存活的对象,分代年龄会+1,达到15移入老年代。
如何查找垃圾对象,gc root查找垃圾对象,利用可达性分析,将可达的对象移入Survivor区,年代+1,剩余的删除。

浙公网安备 33010602011771号