JVM内存模型
2025-06-06 09:53:38 0 举报
JVM内存模型是Java虚拟机中用于指定线程共享内存和非共享内存区域的一套规范。它定义了程序运行时如何分配、管理和回收内存。其中,主要内存区域包括堆(Heap)和栈(Stack),以及方法区(Method Area)、程序计数器(Program Counter)和本地方法栈(Native Method Stack)。
作者其他创作
大纲/内容
B
C
A
三色标记算法(并发标记阶段)黑色: 表示对象已经被垃圾收集器访问过, 且这个对象的所有引用都已经扫描过。 黑色的对象代表已经扫描过, 它是安全存活的, 如果有其他对象引用指向了黑色对象, 无须重新扫描一遍。 黑色对象不可能直接(不经过灰色对象) 指向某个白色对象。灰色: 表示对象已经被垃圾收集器访问过, 但这个对象上至少存在一个引用还没有被扫描过。白色: 表示对象尚未被垃圾收集器访问过。 显然在可达性分析刚刚开始的阶段, 所有的对象都是白色的, 若在分析结束的阶段, 仍然是白色的对象, 即代表不可达
CMS:增量更新的写屏障 G1,Shenandoah:SATB的写屏障ZGC:读屏障
GC Root
开始
实际结果
垃圾回收
垃圾回收器
标记清除算法
标记整理算法
复制算法
回收算法
单线程收集时STW标记-整理算法
E
开始引用后面去除
Serial
D
单线程收集时STW复制算法
G1
多线程收集时STW复制算法
Serial Old
开始没有后面新增
线程私有
Parallel
字节码执行引擎
类装载子系统
JVM虚拟机
CMS
方法区(元空间)常量、静态变量、类元信息
并发某些阶段STW标记-清除算法
ParNew
颜色含义
Parallel Old
公共访问
多线程收集时STW标记-整理算法
堆
本地方法栈
函数0 - 栈帧
FILO (栈)
程序计数器
函数1 - 栈帧
线程2
内存模型
年轻代
栈帧
老年代
函数2 - 栈帧
survivor0
survivor1
线程1
Eden
装载
.class文件
原始快照方式
重新标记阶段
并发标记阶段
验证
加载
当CMS出现"concurrentmode failure",此时会进入stop the world,用serial old垃圾收集器来回收
Minor GC
Full GC
删除
初始化
解析
准备
卸载
使用
并发标记并发清理
defineClass
findClass
loadClass
方法区回收
外部Jar包
应用程序类加载器
扩展类加载器
引导类加载器
通过URLClassLoader#addURL加入
自定义类加载器(不一定存在)
输入文本或“/”选择快捷指令
Full GC 停止系统程序,然后采用单线程进行标记、清理和压缩整理,好空闲出来一批Region来供下一次MixedGC使用,这个过程是非常耗时的。(Shenandoah优化成多线程收集了)
MixedGC 不是FullGC,老年代的堆占有率达到参数(-XX:InitiatingHeapOccupancyPercent)设定的值则触发,回收所有的Young和部分Old(根据期望的GC停顿时间确定old区垃圾收集的优先顺序)以及大对象区,正常情况G1的垃圾收集是先做MixedGC,主要使用复制算法,需要把各个region中存活的对象拷贝到别的region里去,拷贝过程中如果发现没有足够的空region能够承载拷贝对象就会触发一次Full GC
YoungGC YoungGC并不是说现有的Eden区放满了就会马上触发,G1会计算下现在Eden区回收大概要多久时间,如果回收时间远远小于参数 -XX:MaxGCPauseMills 设定的值,那么增加年轻代的region,继续给新对象存放,不会马上做YoungGC,直到下一次Eden区放满,G1计算回收时间接近参数 -XX:MaxGCPauseMills 设定的值,那么就会触发Young GC
并发产生的问题
多标-浮动垃圾在并发标记过程中,如果由于方法运行结束导致部分局部变量(gcroot)被销毁,这个gcroot引用的对象之前又被扫描过(被标记为非垃圾对象),那么本轮GC不会回收这部分内存。这部分本应该回收但是没有回收到的内存,被称之为“浮动垃圾”。浮动垃圾并不会影响垃圾回收的正确性,只是需要等到下一轮垃圾回收中才被清除。另外,针对并发标记(还有并发清理)开始后产生的新对象,通常的做法是直接全部当成黑色,本轮不会进行清除。这部分对象期间可能也会变为垃圾,这也算是浮动垃圾的一部分。
0 条评论
下一页