12 | 垃圾回收(下)
该思维导图由 AI 生成,仅供参考
- 深入了解
- 翻译
- 解释
- 总结
本文介绍了Java虚拟机中的垃圾回收技术,重点讨论了针对新生代的Minor GC和卡表技术。文章首先介绍了Java对象生命周期的动态分析,引出了Java虚拟机的分代回收思想,并详细解释了堆划分、内存分配过程和Minor GC的过程。随后,重点介绍了卡表技术,解释了其在Minor GC中的作用和实现原理。文章还提到了写屏障和虚共享问题,以及Java虚拟机中的垃圾回收器。总结部分对Java虚拟机中垃圾回收器进行了简要介绍,并指出了G1和ZGC的特点。整体来看,本文深入浅出地介绍了JVM垃圾回收的相关知识,对于想深入了解Java虚拟机内存管理的读者具有很高的参考价值。
《深入拆解 Java 虚拟机》,新⼈⾸单¥59
全部留言(86)
- 最新
- 精选
- 钱置顶写的非常棒,又帮我看到了一个小黑盒中的天地。 小结: 1:二八法则-适用于许多的领域,对象在JVM对内存空间的生命周期也同样符合 2:为了更好的JVM性能以及充分利用对象生命周期的二八法则,JVM的作者将JVM的对内存空间进行了分代的处理 3:堆内存空间=年轻代+老年代 年轻代=Eden+from+to 年轻代用于分配新生的对象 Eden-通常用于存储新创建的对象,对内存空间是共享的,所以,直接在这里面划分空间需要进行同步 from-当Eden区的空间耗尽时,JVM便会出发一次Minor GC 来收集新生代的垃圾,会把存活下来的对象放入Survivor区,也就是from区 注意,from和to是变动的 to-指向的Survivor区是空的,用于当发生Minor GC 时,存储Eden和from区中的存活对象,然后再交换from和to指针,以保证下一次Minor GC 时to指向的Survivor区还是空的。 老年代-用于存储存活时间更久的对象,比如:15次Minor GC 还存活的对象就放入老年代中 4:堆内存分代后,会根据他们的不同特点来区别对待,进行垃圾回收的时候会使用不同的垃圾回收方式,针对新生代的垃圾回收器有如下三个:Serial、Parallel Scavenge、Parallel New,他们采用的都是标记-复制的垃圾回收算法。 针对老年代的垃圾回收器有如下三个:Serial Old 、Parallel Old 、CMS,他们使用的都是标记-压缩的垃圾回收算法。 5:TLAB(Thread Local Allocation Buffer)-这个技术是用于解决多线程竞争堆内存分配问题的,核心原理是对分配一些连续的内存空间 6:卡表-这个技术是用于解决减少老年代的全堆空间扫描
作者回复: 好长的总结,赞一个
2018-08-21467 - 公子_小白老师您好 请问JVM分代收集新生代对象进入老年代,年龄为什么是15而不是其他的? 谢谢
作者回复: HotSpot会在对象头中的标记字段里记录年龄,分配到的空间只有4位,最多只能记录到15
2018-08-23563 - javaadu写得真好,搞清楚了之前没掌握透彻的概念: (1)TLAB是为了避免对象分配时对内存的竞争 (2)卡表是为了处理minor gc时老年代对新生代的引用,为了避免整堆扫描而提出了卡表的概念 提个问题:JVM中堆内存根系统的物理内存是如何对应的,这个可以从哪里看?
作者回复: 根系统指的是? GC roots分布在HotSpot中的每个子系统里。可以在源码中搜oops_do
2018-08-17316 - Shine通过GC_roots探索存活对象的时候,有的对象在新生代,有的对象在老年代。如果当前对象处在老年代而且在赃卡中,需要继续深度遍历对象。若不在赃卡中,就没必要进一步深度遍历下去了。不知道我的理解对不?
作者回复: 对的。卡表就是为了避免探索整个老年代,而只将脏表中的对象作为GC roots。
2018-08-1714 - herome老师 建议是能画点图吗 😂 每一篇都是文字。 相信画了图 不仅能让文章通俗易懂,也能让老师的文笔更好。
作者回复: 多谢建议!
2018-08-19213 - Ben老师,有个疑问想请教一下: 如果Eden区和from指向的Survivor区存活对象大于to指向的Survivor区的大小,那么JVM会如何处理?
作者回复: 会按对象年龄晋升最老的那些至老年代。极端情况,假设survivor 区大小为0,那就是直接把eden区的存活对象晋升过去了
2019-12-2327 - Jimbol看某些资料介绍说tlab是将对象创建在栈内存上,并且与逃逸分析一起用,这样在释放栈内存时就直接将这部分内存一起释放了,降低了gc成本。您讲解的说tlab是提前在堆内存中分配空间,这样没有降低gc成本呀!
作者回复: HotSpot不支持在栈上新建对象。 C2里的逃逸分析是静态分析,和TLAB没什么关系。它和标量替换一起使用,能够完全不分配对象,仅在寄存器中维护这个对象的字段。
2018-08-1827 - abs新声代回收的时候会把老年代的所有对象当做gcroot吗
作者回复: 原本是的。但使用了脏卡技术之后,JVM只需要把脏卡中的对象当成GC roots
2018-08-296 - Alex RaoTLAB 和 工作内存是什么关系?
作者回复: 如果你说的是JMM中的工作内存,那是JMM抽象出来的一个概念,在现实的体系架构中可以映射为CPU中的缓存,属于硬件技术。 TLAB是用来优化多线程分配的,属于软件技术。两者没啥关系。
2018-08-196 - 郭俊杰老师,你好,一直想问个问题,多线程访问共享变量会存在线程安全问题,那么方法内部通过new的局部变量是不是也存在安全问题呢?希望老师帮忙回答下感谢
作者回复: 如果你把new后的对象发布出去,就是放到其他共享变量中,也会存在线程安全问题。如果new后只是在方法中使用该对象而不作为参数传出去(以它为调用者的实例方法也不会传出去),那么没有问题。
2018-08-185