11 | 垃圾回收(上)
该思维导图由 AI 生成,仅供参考
引用计数法与可达性分析
- 深入了解
- 翻译
- 解释
- 总结
本文介绍了Java虚拟机中的垃圾回收机制及其基础知识。首先介绍了引用计数法和可达性分析两种垃圾回收算法,指出可达性分析算法能有效解决循环引用问题。文章详细解释了Stop-the-world机制和安全点的概念,以及在多线程环境下的应用。此外,还介绍了垃圾回收的三种方式:清除、压缩和复制,并指出现代垃圾回收器往往会综合这些方式。总的来说,本文通过深入浅出的方式,解释了垃圾回收的基础知识和相关机制,对读者快速了解Java虚拟机中的垃圾回收提供了全面的概览。
《深入拆解 Java 虚拟机》,新⼈⾸单¥59
全部留言(74)
- 最新
- 精选
- 旭东(Frank)置顶赞,这种循序渐进的讲法,不知道了怎么工作,还知道了为啥要设计成这样,Why和what都和谐的在一起讲了2018-08-2818
- 钱置顶非常感谢,此篇可用通俗易懂来形容,其他同学问的问题也很棒! 小结: 1:垃圾回收-核心工作就是回收垃圾,哪关键点回来了。什么是垃圾?这个垃圾需要分类嘛?怎么定位垃圾?怎么回收垃圾?回收垃圾的方法都有哪些?他们都有什么优缺点?另外,就是我们为什么要学习垃圾回收? 2:站在JVM的视角来看 垃圾-就是无用对象所占用的堆内存空间 貌似不需要垃圾分类,识别垃圾并回收就行 定位垃圾,是垃圾回收的关键点 晚安💤,明天继续写2018-08-1632
- 钱非常感谢,此篇可用通俗易懂来形容,其他同学问的问题也很棒! 小结: 1:垃圾回收-核心工作就是回收垃圾,哪关键点回来了。什么是垃圾?这个垃圾需要分类嘛?怎么定位垃圾?怎么回收垃圾?回收垃圾的方法都有哪些?他们都有什么优缺点?另外,就是我们为什么要学习垃圾回收? 2:站在JVM的视角来看 垃圾-就是无用对象所占用的堆内存空间 垃圾分类-貌似不需要垃圾分类,识别垃圾并回收就行 定位垃圾-是垃圾回收的关键点,无用的对象占用的堆空间即是垃圾,那就需要先定位无用的对象,这里的无用是不再使用的意思,咋判断呢?文中介绍了两种方法,计数法和标记法(祥看原文)核心在于能定位出无用的对象,后出现的方法往往比早出现的更好一点,这里也一样,标记法能解决计数法,解决不了的循环引用不能回收的问题,但是也存在其他的问题,误报和漏报的问题,误报浪费点垃圾回收的机会浪费点空间,漏报在多线程并发工作时可能会死JVM的,所以,比较严重,所以,JVM采用了简单粗暴的stop-the-world的方式来对待,所以,老年代的回收有卡顿的现象 怎么回收垃圾-定位出垃圾,回收就是一个简单的事情了,当然也非常关键,把要回收的堆内存空间标记为可继续使用就行,下次有新对象能在此空间创建就行 回收垃圾的方法-文中介绍了三种,清除、压缩、复制 清除法-简单,但易产生碎片,可能总空间够但分配不了的问题 压缩法-能解决清除法的问题,但是复杂且耗性能 复制法-折衷一些,但是空间利用率低,总之,各有千秋 为什么要学-这个最容易,因为面试需要、装逼需要、升职加薪需要、人类天生好奇、还有免于被鄙视及可以鄙视其他人
作者回复: 赞!
2018-08-17643 - 钱疑问❓ 1:JVM的stop-the-world机制非常不友好,有哪些解决之道?原理是什么? 2:压测时出现频繁的gc容易理解,但是有时出现毛刺是因为什么呢? 3:fullgc有卡顿,对性能很不利,怎么避免呢?
作者回复: 1. 采用并行GC可以减少需要STW的时间。它们会在即时编译器生成的代码中加入写屏障或者读屏障。 2. Y轴应该是时间,那毛刺就是长暂停。一般Full GC就会造成长暂停。 3. 通过调整新生代大小,使对象在其生命周期内都待在新生代中。这样一来,Minor GC时就可以收集完这些短命对象了。
2018-08-17329 - Leon Wong老师你好,例子里的foo方法中的for循环,其中i变量类型我从int型改成long型后,长暂停的现象不存在了,请问是为何?
作者回复: 这是C2一个诡异的地方。 for (int i=start; i<limit; i++) {..} 对于int类型的循环变量i,如果满足 1) 基于该循环变量的循环出口只有一个,即i < limit,2) 循环变量随着迭代的增量为常数,例子中i++即增量为1,以及循环变量的上限(当增量为负数时则是下限)为循环无关的,即limit应是循环无关,那么C2会将其判断成计数循环(counted loop),然后默认不插入safepoint。 而对于long类型的循环变量,C2直接识别为非计数循环,需要插入safepoint。
2018-09-11317 - 浪迹江湖突发奇想:如果 GC 将引用计数算法和可达性分析算法结合起来使用会怎样? 循环引用毕竟是少数,如果先用引用计数算法回收掉大部分对象,再对剩余的小部分对象采用可达性分析算法解决循环引用问题。可能比只使用可达性分析算法带来更好的回收效率。
作者回复: 赞想法!不过我认为没有达到更好的回收效率,因为垃圾回收标记的是非垃圾,剩余没有标记的对象是垃圾。用引用计数法清理后,可达性分析仍需遍历所有活着的对象。 但是可以将引用计数做成minor minor GC,只有当引用计数回收不了垃圾时,再触发可达性分析。感兴趣的话可以深入探索一下业界其他非Java runtime的垃圾回收算法。
2018-09-2612 - 正是那朵玫瑰老师有几个不明白的地方,误报和漏报不太明白: 1、假设A引用开始指向A1对象:A------>A1,按老师说的误报就是将引用A指向null:A------>null,那么此时A1对象不是没有引用了,不就可以垃圾回收了么,为什么会错过垃圾回收的机会呢? 2、漏报,是将A引用指向一个未被访问的对象假设对象为B:A----->B,此时A引用原来指向的对象应该没有引用了吧,为什么会垃圾回收器可能会回收事实上仍被引用的对象呢?
作者回复: 这里指的是,GC已经标记完成,然后其他线程进行修改的情况(也是并发GC所要解决的问题)。 当GC标记完成,还未开始回收时,你更新了其中一个引用,使之指向null,那么原来指向的对象本可以被回收的。 如果指向一个新的对象,这个对象可没有被标记为不能回收,垃圾回收器就直接给回收掉了
2018-08-158 - WolvesLeader很是不明白,我的理解有没有stop the word 是和垃圾回收器有关的,看完之后怎么觉得您的意思是,不管什么垃圾回收器都会出现stop the word
作者回复: 目前的垃圾回收器多多少少需要stop the world,但都在朝着尽量减少STW时间发展。 完全的并发GC算法是存在的,但是在实现上一般都会在枚举GC roots时进行STW。
2018-08-177 - life is short, enjoy mor...老师,我心中有一个疑惑。 压缩算法是不是也用到了复制呢?因为我觉得在压缩的过程中,也需要把存活的内存进行转移,而转移也就是复制吧? 麻烦老师给回答一下~
作者回复: 确实是需要复制数据,这样起名主要是为了区分复制到同一个区域中(需要复杂的算法保证引用能够正确更新),还是复制到另一个区域中(可以复制完后统一更新引用)。
2018-10-164 - Jerry银银老师,以下这段话是不是有误? 误报和漏报反了! 漏报应该是没有什么伤害,会让GC损失部分垃圾回收的机会。误报才比较麻烦,可能回收仍被引用的对象!! “误报并没有什么伤害,Java 虚拟机至多损失了部分垃圾回收的机会。漏报则比较麻烦,因为垃圾回收器可能回收事实上仍被引用的对象内存。一旦从原引用访问已经被回收了的对象,则很有可能会直接导致 Java 虚拟机崩溃。”
作者回复: 误报是指可达性分析误认为某个对象是可达的,实际不可达。漏报是指可达性分析没有发现某个对象可达。 这里需要明确,可达性分析会找出非垃圾,而其他对象通通被认为是垃圾。
2020-01-0442