-
现有的垃圾回收器的目标是: 在保证最大吞吐量优先的情况下,合理降低停顿时间
-
对于一个对象HotSpot抛弃了使用引用计数的方式判断一个普通对象的生死, 而是使用可达性分析算法来判断一个对象的生死
-
其核心思想就是: 通过一系列的GC Roots对象作为起点开始向下搜素, 搜索走过的的路程称之为引用链, 对于一个对象, 如果没有一个引用链与GCRoot相连, 那么它就是一个不可达的对象, 虚拟机就会证明此对象不可用
-
但是在可达性分析算法中不可达的对象,也并非"非死不可"的,这时候他们暂时处在"缓刑"阶段。要宣告一个对象的真正死亡,至少要经历两次标记过程 :
-
如果对象在进行可达性分析之后发现没有与GC Roots相连接的引用链,那它将会被第一次标记并且进行一次筛选,筛选的条件是此对象是否有必要执行finalize()方法。当对象没有覆盖finalize()方法或者finalize()方法已经被JVM调用过,虚拟机会将这两种情况都视为"没有必要执行",此时的对象才是真正"死"的对象。
-
如果这个对象被判定为有必要执行finalize()方法,那么这个对象将会被放置在一个叫做F-Queue的队列之中,并在稍后由一个虚拟机自动建立的、低优先级的Finalizer线程去执行它(这里所说的执行指的是虚拟机会触发finalize()方法)。finalize()方法是对象逃脱死亡的最后一次机会,稍后GC将对F-Queue中的对象进行第二次小规模标记,如果对象在finalize()中成功拯救自己(只需要重新与引用链上的任何一个对象建立起关联关系即可),那在第二次标记时它将会被移除出"即将回收"的集合;如果对象这时候还是没有逃脱,那基本上它就是真的被回收了。
- 但是对于类对象的删除的要求的非常严格的, 删除一个类对选哪个要满足下面三个条件
-
该类的所有实例都已经回收
-
该类的类加载器都已经删除
-
该类的对应Class对象没有在任何地方引用, 并且这个类对象没有在任何地方通过反射访问过该类
-
只有满足上述三个条件. 回收器才会考虑回收回收这个类对象
-
而对于真正的回收算法. 有
-
标记清除算法, 但是会产生大量的内存碎片
-
标记复制算法, 需要较大的空间, 而且复制起来比较耗时, 但是对于分代回收思想的年轻代, 可以使用复制算法
-
标记整理算法, 对于老年代来说很友好, 因为其没有较大的内存空间, 他的思想就是将有用对象进行整理,防止出现内存碎片, 所以在实际的老年代回收提出了标记-清整算法, 就是先进行标记清除, 害怕出现内存碎片, 就再进行一次标记整理算法
-
分代手机算法, 对于这个算法而言就是把堆区分为年轻代和老年代, 年轻代存放一些刚生产的对象, 老年代放置一些大对象或者经年轻代没杀死的对象, 对于年轻代他们使用Minor GC, 该思想采用复制算法, 收集频率也高, 回收速度也快
-
虚拟机在进行minorGC之前会判断老年代最大的可用连续空间是否大于新生代的所有对象总空间,如果大于的话,直接执行minorGC。
-
对于老年代和永久代他们使用full GC , 这个的收集频率就比较慢, 一般是快满的时候才进行一次, 采用标记整理算法, 速度会比Minor GC慢10倍左右
-
显示调用System.gc()方法也是直接调用Full GC
- 如果说上面我们讲的收集算法是内存回收的方法论,那么垃圾收集器就是内存回收的具体实现。以下讲的收集器基于JDK1.7的G1收集器之后的HotSpot虚拟机,这个JVM包含的所有收集器如下图所示
-
垃圾收集器在工作区域划分, 有对年轻代进行垃圾回收的, 有对老年代进行垃圾回收的, 还有老少通吃的
-
对于工作方式有和工作线程并行的垃圾回收器, 有和工作线程并发的垃圾回收器
-
如果是并行回收, 工作线程就必须等待, 如果是并发回收, 指工作线程和回收线程可以同时执行
Serial收集器(新生代收集器,串行GC)
- 特点
- 单线程收集器, 但它的 **“单线程”的意义并不仅仅说明它只会使用一个CPU或一条收集线程去
完成垃圾收集工作,更重要的是在它进行垃圾收集时,必须暂停其他所有的工作线程,直到它收集结束(StopThe World)**
- 应用场景:
Serial收集器是虚拟机运行在Client模式下的默认新生代收集器。
- 优势:
-
简单而高效(与其他收集器的单线程比),对于限定单个CPU的环境来说,Serial收集器由于没有线程交互的开销,
-
专心做垃圾收集,采用串行执行方式省去了二次重新标记自然可以获得最高的单线程收集效率。 实际上到现在为止 : 它依然是虚拟机运行在Client模式下的默认新生代收集器
ParNew收集器(新生代收集器,并行GC)
- 特点
-
是Serial收集器的多线程版本, 使用多条线程去进行垃圾的回收
-
其余包括Serial的控制参数, 收集算法, stop the world, 回收策略和Serial是一样的
-
ParNew收集器是许多运行在Server模式下的虚拟机中首选的新生代收集器
- 对比
- ParNew在但CPU的环境下绝对没有Serial好, 因为其多线程的交互开销太大, 所以对于CPU数目较多的时候, 他还是明显优于Serial的
Parallel Scavenge(PS)收集器(新生代收集器,并行GC)
- 特点
-
采用复制算法, 并行执行的多线程收集器, 并行的话就是需要停顿工作线程
-
其可以使用XX:MaxGCPauseMillis 控制最大的垃圾收集停顿时间 XX:GCRatio 直接设置吞吐量的大小
- 应用场景
其可以设置停顿时间, 和吞吐量, 所以可以有良好的用户体验, 可以很好的利用CPU提高响应效率, 可以尽快完成任务, 但是一定程度上浪费了内存空间, 所以主要适用于实现用空间换取时间的场景, 或者一些我们可以动态的对其优化的场景
- 对比
PS于ParNew对比来说, PS可以实现自适应调节参数
Serial Old收集器(老年代收集器,串行GC)
- 特点
-
老年代收集器, 是一个单线程模式的收集器
-
采用标记整理算法
- 应用场景
在Client模式和Server模式下都会使用到这个垃圾回收器, 但是他是在Client模式下为主要的使用, 在Server模式下是作为CMS的后备方案
Parallel Old收集器(老年代收集器,并行GC)
- 特点
-
回收老年代版本的收集器, 采用多线程方式和标记整理算法
-
其也可以设置自适应的吞吐量和暂停时间
- 应用场景
在注重吞吐量以及CPU资源敏感的场合,都可以优先考虑Parallel Scavenge加Parallel Old收集器。
CMS收集器(老年代收集器,并发GC)
- 特点
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加V获取:vip1024b (备注Java)
总结
以上是字节二面的一些问题,面完之后其实挺后悔的,没有提前把各个知识点都复习到位。现在重新好好复习手上的面试大全资料(含JAVA、MySQL、算法、Redis、JVM、架构、中间件、RabbitMQ、设计模式、Spring等),现在起闭关修炼半个月,争取早日上岸!!!
下面给大家分享下我的面试大全资料
- 第一份是我的后端JAVA面试大全
后端JAVA面试大全
- 第二份是MySQL+Redis学习笔记+算法+JVM+JAVA核心知识整理
MySQL+Redis学习笔记算法+JVM+JAVA核心知识整理
- 第三份是Spring全家桶资料
MySQL+Redis学习笔记算法+JVM+JAVA核心知识整理
一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
- 第三份是Spring全家桶资料
[外链图片转存中…(img-4OxfafV0-1712650816610)]
MySQL+Redis学习笔记算法+JVM+JAVA核心知识整理
一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
[外链图片转存中…(img-VC7S0fsh-1712650816610)]