当前位置:首页 >探索 >一文吃透JVM分代回收机制 机制所以比Scavenge GC要慢

一文吃透JVM分代回收机制 机制所以比Scavenge GC要慢

2024-06-26 02:06:06 [百科] 来源:避面尹邢网

一文吃透JVM分代回收机制

作者:陈烨123 开发 前端 对整个堆进行整理,文吃包括Young、分代Tenured和Perm。回收Full GC因为需要对整个对进行回收,机制所以比Scavenge GC要慢,文吃因此应该尽可能减少Full GC的分代次数。在对JVM调优的回收过程中,很大一部分工作就是机制对于FullGC的调节。有如下原因可能导致Full GC。文吃

为什么要分代

    分代的分代垃圾回收策略,是回收基于这样一个事实:不同的对象的生命周期是不一样的。因此,机制不同生命周期的文吃对象可以采取不同的收集方式,以便提高回收效率。分代

    在Java程序运行的回收过程中,会产生大量的对象,其中有些对象是与业务信息相关,比如Http请求中的Session对象、线程、Socket连接,这类对象跟业务直接挂钩,因此生命周期比较长。但是还有一些对象,主要是程序运行过程中生成的临时变量,这些对象生命周期会比较短,比如:String对象,由于其不变类的特性,系统会产生大量的这些对象,有些对象甚至只用一次即可回收。

一文吃透JVM分代回收机制 机制所以比Scavenge GC要慢

    试想,在不进行对象存活时间区分的情况下,每次垃圾回收都是对整个堆空间进行回收,花费时间相对会长,同时,因为每次回收都需要遍历所有存活对象,但实际上,对于生命周期长的对象而言,这种遍历是没有效果的,因为可能进行了很多次遍历,但是他们依旧存在。因此,分代垃圾回收采用分治的思想,进行代的划分,把不同生命周期的对象放在不同代上,不同代上采用最适合它的垃圾回收方式进行回收。

一文吃透JVM分代回收机制 机制所以比Scavenge GC要慢

如何分代

一文吃透JVM分代回收机制 机制所以比Scavenge GC要慢

图片图片

如图所示:

    虚拟机中的共划分为三个代:年轻代(Young Generation)、年老点(Old Generation)和持久代(Permanent Generation)。其中持久代主要存放的是Java类的类信息,与垃圾收集要收集的Java对象关系不大。年轻代和年老代的划分是对垃圾收集影响比较大的。

对象分类

        这种算法并不是一种新的算法,而是根据对象的存活周期的不同而将内存分为几块,分别为新生代、老年代和永久代。

        新生代:朝生夕灭的对象(例如:方法的局部变量等)。

        老年代:存活得比较久,但还是要死的对象(例如:缓存对象、单例对象等)。

        永久代:对象生成后几乎不灭的对象(例如:加载过的类信息)。

内存区域

        回想一下之前jvm对内存的划分,我们可能就已经猜到了,新生代和老年代都在java堆,永久代在方法区。

java堆对象的回收

        现在,我们来看看分代收集算法是如何针对堆内存进行回收的。

        新生代:采用复制算法,新生代对象一般存活率较低,因此可以不使用50%的内存作为空闲,一般的,使用两块10%的内存

作为空闲和活动区间,而另外80%的内存,则是用来给新建对象分配内存的。一旦发生GC,将10%的活动区间与另外80%中存

活的对象转移到10%的空闲区间,接下来,将之前90%的内存全部释放,以此类推,下面还是用一张图来说明:

        解释下,堆大小=新生代+老年代,新生代与老年代的比例为1:2,新生代细分为一块较大的Eden空间和两块较小的Survivor空间,分别被命名为from和to。

        老年代:老年代中使用“标记-清除”或者“标记-整理”算法进行垃圾回收,回收次数相对较少,每次回收时间比较长。

方法区对象回收

        永久代指的是虚拟机内存中的方法区,永久代垃圾回收比较少,效率也比较低,但也必须进行垃圾回收,否则永久代内存

不够用时仍然会抛出OutOfMemoryError异常。永久代也使用“标记-清除”或者“标记-整理”算法进行垃圾回收。

什么情况下触发垃圾回收

    由于对象进行了分代处理,因此垃圾回收区域、时间也不一样。GC有两种类型:Scavenge GC和Full GC。

Scavenge GC

    一般情况下,当新对象生成,并且在Eden申请空间失败时,就会触发Scavenge GC,对Eden区域进行GC,清除非存活对象,并且把尚且存活的对象移动到Survivor区。然后整理Survivor的两个区。这种方式的GC是对年轻代的Eden区进行,不会影响到年老代。因为大部分对象都是从Eden区开始的,同时Eden区不会分配的很大,所以Eden区的GC会频繁进行。因而,一般在这里需要使用速度快、效率高的算法,使Eden去能尽快空闲出来。

Full GC

    对整个堆进行整理,包括Young、Tenured和Perm。Full GC因为需要对整个对进行回收,所以比Scavenge GC要慢,因此应该尽可能减少Full GC的次数。在对JVM调优的过程中,很大一部分工作就是对于FullGC的调节。有如下原因可能导致Full GC:

责任编辑:武晓燕 来源: java知路 JVMFullGC调优

(责任编辑:焦点)

    推荐文章
    热点阅读