当前位置: 首页 > 科技观察

面试官问我JVM的GC分代收集算法为什么这么设计

时间:2023-03-20 12:57:53 科技观察

面试官问我JVM的GC分代收集算法为什么要设计成这样GC算法,但是问我为什么要这样设计,搞得学妹很疑惑,阿芬差点把学长砸了女孩。面试官问这个问题,就是想考验你,知道为什么,知道为什么吗?今天阿芬就简单的说说这个。JVM的垃圾回收机制我们先来说说这个回收机制的算法,如图。目前面试中经常被问到的垃圾回收算法就这些。下面分别说说,最后说说分代收集为什么选择不同的算法。Mark-SweepAlgorithmMark-Sweep我们都知道,标记清除算法是垃圾收集算法中最基本的算法,因为标记算法只有两个阶段。标记的对象都是需要回收的对象。当执行到清理阶段时,这些被标记的对象将被直接彻底清除。如果是这样的话,那就有问题了。你看,如果灰色的是我们的内存空间,然后我们需要清除回收的对象,我们不能保证回收的对象会连续排列在一起,比如所有需要回收的对象都排列在内存顶层空间。这是不太可能的,所以在进行清理之后,这些未使用的内存空间就变成了未使用的内存空间。连续的内存空间。mark-and-sweep算法最大的缺点就是碎片化非常严重。如果有一个很大的对象要存储,但是内存中没有连续的空间,那么就会没有可用的空间来存储它。为了解决严重的碎片情况,有如下垃圾回收算法。为了解决内存碎片严重的问题,复制算法根据内存容量将内存分成大小相等的两块。一次只使用其中一个。当这块内存满了的时候,将存活的对象复制到另一个内存中,以清除已使用的内存。其实这样一来,在大家看来,有什么问题吗?它解决了碎片严重的情况,但是它直接将内存空间一分为二。如果我们当前要回收的对象少,存活的对象多,那么这个复制算法的效率真的很高。那些有点低。那么有妥协吗?又来了一个算法,标记紧凑算法(Mark-Compact)。这个算法很特别。标记阶段与Mark-Sweep算法相同,但在排序时有所不同。标记后,对象并没有被清理,而是将存活的对象移向内存的一端。然后清除结束边界之外的对象。即有可能存活的对象先移到左边,然后需要清理的对象移到右边,这样既保证了内存空间的连续性,又提高了效率。那么我们可以回到这个题目,GC分代收集,为什么要这样设计。世代相传很容易理解。毕竟我们都知道一个共同的知识点,就是GC堆内存分为老年代和新生代。如果要选择一种算法,就必须从它们的本质入手。老年代:存活对象数量多,需要处理的对象数量少。存活对象数量少,待处理对象数量大。清理的对象多,需要清理的对象少。复制算法是因为每次都复制存活对象,新生代的存活对象比较少,所以这个时候可以使用复制算法。也就是说,新生代划分的大Eden区和两个Survivor区,每次使用都是Eden区和其中一个Survivor区。回收时,将两个空间中的存活对象复制到另一个Survivor区。所以因为新生代的这个特点,所以采用了复制算法。老年代使用Mark-Compact算法是因为每次只回收少量对象。这也是为什么在面试的时候,面试官会问你为什么GC分代收集选择不同的算法。JVM的垃圾回收器,一般面试一般会重点问垃圾回收机制和算法。其中很少涉及JVM的垃圾收集器。今天阿芬就来科普一下这方面的知识。串行收集器(新一代)最早的收集器使用复制算法暂停所有用户线程。它的特点是简单、高效、单线程,但是容易造成全局暂停,也就是我们常说的STW(globalpause)。STW:全局暂停,Java代码停止运行,native代码继续运行,但不能与JVM交互也暂停所有用户线程。主要与CMS收集器配合使用。ParallelScavengecollector(新一代)吞吐量收集器,该收集器侧重于吞吐量。JVM中有参数可以配置-XX:MaxGCPauseMillis:控制最大垃圾回收暂停时间-XX:GCTimeRatio:设置throughput的大小,取值0-100,系统花费不超过1/(1+n)timeongarbagecollectionSerialOldcollector(oldgeneration)老年代收集器使用mark-sort算法CMS收集器(oldgeneration)算法使用mark-clear算法实现。一般这个面试的问题可能比较多,因为属于并发收集器,因为不会像上面说的收集器那样,直接导致所有用户线程停止,直到清完为止。,但在标记过程中会有短暂的停顿。相反,首先完成初始标记,然后是并发标记,再标记的纠正并发标记,最后是并发清除。G1收集器G1(Garbage-First)收集器将堆内存划分为不同的区域,然后对它们并发执行垃圾收集。G1收集器的设计目标是取代CMS收集器。与CMS相比,不会产生大量的内存碎片,并且可以增加预测机制。用户可以指定预期的暂停时间(可以通过-XX:MaxGCPauseMills=n最大暂停时间来配置)内存,单机程序-XX:+UseSerialGC多CPU,要求最大吞吐量,如后台计算应用-XX:+UseParallelGC或-XX:+UseParallelOldGC多CPU,追求低停顿时间,需要快速响应如互联网应用-XX:+UseConcMarkSweepGC-XX:+ParNewGC以上就是阿凡在面试中给大家带来的关于JVM的一些小知识点,有兴趣的可以继续深入了解JVM知识,这样大家可以保证,如果面试官在面试的时候换了问题,就不会这样了。