7種類のJVMガベージコレクタの特性、利点と欠点と使用シナリオ(図倍)

トップをクリックして「IT牧場」を選択し、「設定スター」技術乾燥品が毎日配信!

一般的なガベージコレクタ

次のように今、共通のガベージコレクタが要約されています。

コレクターの新世代:

  • シリアル

  • ParNew

  • パラレル清掃を

コレクタ歳:

  • シリアル古いです

  • CMS

  • パラレル古いです

ヒープメモリのガベージコレクタ: G1

各ガベージコレクタ間の接続は、彼らが使用できること、があります。

第二に、新世代のガベージコレクタ

(1)シリアルコレクタ

シリアルは、レプリケーションを使用して、シングルスレッドのコレクターの新世代のために、ガベージコレクションアルゴリズムです。だけではなく、スレッドによるシリアルガベージコレクションは、ガベージコレクションを実行すると、それは同時に収集し、すべてのユーザー・スレッドは、(世界の停止)一時停止する必要があります。

グランド側に時間をクリーニングに家庭のお母さんのような、確かではないきれいな側は、製造やゴミ、再びごみながら、このライブシャシ侯も積み上げ、彼の息子の投げ紙吹雪を聞かせします。

以下は、シリアル、シリアル旧コレクターやコレクターは、ガベージコレクションのための模式図を組み合わせた安全な地点に、ユーザは、すべてのスレッドが停止したときに、スレッドが集まり、完成後にガベージコレクションのコピーアルゴリズムを使用して、単一のスレッドにシリアルコレクタを実行されていますユーザスレッドが実行を再開します。

アプリケーションシナリオ:クライアントモード(デスクトップアプリケーション)、シングルコアサーバ。

-XXことができます。コレクターの新世代として選択+ UserSerialGCシリアルを。

(2)ParNewコレクタ

シリアルのParNewマルチスレッドバージョン、シリアルの間には、他の違いはありません。シングルコアCPU環境でParNewとシリアルコレクタよりも良い結果を達成することはありませんが、それはデフォルトのスレッド数が同じと上のCPUを収集するには、-XXことができます:ガベージコレクションParallelGCThreadsのためにスレッド数を設定します。

ユーザスレッドは、安全なポイントに実行されたすべてのスレッドが中断、ParNewコレクタはマルチスレッドのために、収集完成後のガベージコレクションのための複製アルゴリズムを使用している場合は、次のはParNewコレクタと概略ガベージコレクションと組み合わせシリアルオールドコレクターでありますユーザスレッドが実行を再開します。

該当するシーン:マルチコアサーバ、およびCMSコレクタを使用しました。-XXを使用する場合:コレクターの新世代としてParNewを指定するには、+ UseParNewGC:+ UserConcMarkSweepGCコレクターの古いとしてCMSを選択する際に、コレクターの新世代がParNewデフォルトです、あなたも-XXを使用することができます。

(3)並列スカベンジコレクタ

パラレル清掃を、それがParNew異なり、コレクターのためのマルチスレッドの新世代ですParNew目標は、制御スループットを達成するために、可能な限り、ガベージコレクションの休止時間のユーザスレッドは、並列スカベンジ目標があるときに短縮することであるです。

スループットはCPUの合計時間の割合は、[タイムコード生成、実行ユーザ/(ユーザコードの実行時間のガベージコレクション時間+)]、仮想マシンは100分の合計を実行するよう、ゴミ特定=を行うユーザスレッドを実行するためのCPU時間であります収集は、1分を費やし、スループットが99%であること。後者の時間は各停留所で短縮されているが、例えば100秒ごと、10秒ごとに休止、ガベージコレクタを収集するために、以下の2つのシナリオ、ガベージコレクタとごと50秒を収集し、すべての7秒は、滞留時間が、低い全体のスループット、CPU使用率は一般的に低くなっています。

 

 

-XXことができます:コレクターは、どのくらいの完全な回復とMaxGCPauseMillisメモリを設定することができ-XX:GCTimeRatioを正確にスループットを制御します。

如下是 Parallel 收集器和 Parallel Old 收集器结合进行垃圾收集的示意图,在新生代,当用户线程都执行到安全点时,所有线程暂停执行,ParNew 收集器以多线程,采用复制算法进行垃圾收集工作,收集完之后,用户线程继续开始执行;在老年代,当用户线程都执行到安全点时,所有线程暂停执行,Parallel Old 收集器以多线程,采用标记整理算法进行垃圾收集工作。

适用场景:注重吞吐量,高效利用 CPU,需要高效运算且不需要太多交互。

可以使用 -XX:+UseParallelGC 来选择 Parallel Scavenge 作为新生代收集器,jdk7、jdk8 默认使用 Parallel Scavenge 作为新生代收集器。

三、老年代垃圾收集器

(1)Serial Old 收集器

Serial Old 收集器是 Serial 的老年代版本,同样是一个单线程收集器,采用标记-整理算法。

如下图是 Serial 收集器和 Serial Old 收集器结合进行垃圾收集的示意图:

适用场景:Client 模式(桌面应用);单核服务器;与 Parallel Scavenge 收集器搭配;作为 CMS 收集器的后备预案。

(2)CMS(Concurrent Mark Sweep) 收集器

CMS 收集器是一种以最短回收停顿时间为目标的收集器,以 “ 最短用户线程停顿时间 ” 著称。整个垃圾收集过程分为 4 个步骤:

① 初始标记:标记一下 GC Roots 能直接关联到的对象,速度较快。

② 并发标记:进行 GC Roots Tracing,标记出全部的垃圾对象,耗时较长。

③ 重新标记:修正并发标记阶段引用户程序继续运行而导致变化的对象的标记记录,耗时较短。

④ 并发清除:用标记-清除算法清除垃圾对象,耗时较长。

整个过程耗时最长的并发标记和并发清除都是和用户线程一起工作,所以从总体上来说,CMS 收集器垃圾收集可以看做是和用户线程并发执行的。

CMS 收集器也存在一些缺点:

对 CPU 资源敏感:默认分配的垃圾收集线程数为(CPU 数+3)/4,随着 CPU 数量下降,占用 CPU 资源越多,吞吐量越小

无法处理浮动垃圾:在并发清理阶段,由于用户线程还在运行,还会不断产生新的垃圾,CMS 收集器无法在当次收集中清除这部分垃圾。同时由于在垃圾收集阶段用户线程也在并发执行,CMS 收集器不能像其他收集器那样等老年代被填满时再进行收集,需要预留一部分空间提供用户线程运行使用。当 CMS 运行时,预留的内存空间无法满足用户线程的需要,就会出现 “ Concurrent Mode Failure ”的错误,这时将会启动后备预案,临时用 Serial Old 来重新进行老年代的垃圾收集。

因为 CMS 是基于标记-清除算法,所以垃圾回收后会产生空间碎片,可以通过 -XX:UserCMSCompactAtFullCollection 开启碎片整理(默认开启),在 CMS 进行 Full GC 之前,会进行内存碎片的整理。还可以用 -XX:CMSFullGCsBeforeCompaction 设置执行多少次不压缩(不进行碎片整理)的 Full GC 之后,跟着来一次带压缩(碎片整理)的 Full GC。

适用场景:重视服务器响应速度,要求系统停顿时间最短。可以使用 -XX:+UserConMarkSweepGC 来选择 CMS 作为老年代收集器。

(3)Parallel Old 收集器

Parallel Old 收集器是 Parallel Scavenge 的老年代版本,是一个多线程收集器,采用标记-整理算法。可以与 Parallel Scavenge 收集器搭配,可以充分利用多核 CPU 的计算能力。

适用场景:与Parallel Scavenge 收集器搭配使用;注重吞吐量。jdk7、jdk8 默认使用该收集器作为老年代收集器,使用 -XX:+UseParallelOldGC 来指定使用 Paralle Old 收集器。

四、新生代和老年代垃圾收集器

G1 收集器

G1 收集器是 jdk1.7 才正式引用的商用收集器,现在已经成为 jdk9 默认的收集器。前面几款收集器收集的范围都是新生代或者老年代,G1 进行垃圾收集的范围是整个堆内存,它采用 “ 化整为零 ” 的思路,把整个堆内存划分为多个大小相等的独立区域(Region),在 G1 收集器中还保留着新生代和老年代的概念,它们分别都是一部分 Region,如下图:

每一个方块就是一个区域,每个区域可能是 Eden、Survivor、老年代,每种区域的数量也不一定。JVM 启动时会自动设置每个区域的大小(1M ~ 32M,必须是 2 的次幂),最多可以设置 2048 个区域(即支持的最大堆内存为 32M*2048 = 64G),假如设置 -Xmx8g -Xms8g,则每个区域大小为 8g/2048=4M。

为了在 GC Roots Tracing 的时候避免扫描全堆,在每个 Region 中,都有一个 Remembered Set 来实时记录该区域内的引用类型数据与其他区域数据的引用关系(在前面的几款分代收集中,新生代、老年代中也有一个 Remembered Set 来实时记录与其他区域的引用关系),在标记时直接参考这些引用关系就可以知道这些对象是否应该被清除,而不用扫描全堆的数据。

G1 收集器可以 “ 建立可预测的停顿时间模型 ”,它维护了一个列表用于记录每个 Region 回收的价值大小(回收后获得的空间大小以及回收所需时间的经验值),这样可以保证 G1 收集器在有限的时间内可以获得最大的回收效率。

如下图所示,G1 收集器收集器收集过程有初始标记、并发标记、最终标记、筛选回收,和 CMS 收集器前几步的收集过程很相似:

① 初始标记:标记出 GC Roots 直接关联的对象,这个阶段速度较快,需要停止用户线程,单线程执行。

② 并发标记:从 GC Root 开始对堆中的对象进行可达新分析,找出存活对象,这个阶段耗时较长,但可以和用户线程并发执行。

③ 最终标记:修正在并发标记阶段引用户程序执行而产生变动的标记记录。

④ 筛选回收:筛选回收阶段会对各个 Region 的回收价值和成本进行排序,根据用户所期望的 GC 停顿时间来指定回收计划(用最少的时间来回收包含垃圾最多的区域,这就是 Garbage First 的由来——第一时间清理垃圾最多的区块),这里为了提高回收效率,并没有采用和用户线程并发执行的方式,而是停顿用户线程。

适用场景:要求尽可能可控 GC 停顿时间;内存占用较大的应用。可以用 -XX:+UseG1GC 使用 G1 收集器,jdk9 默认使用 G1 收集器。

五、JVM垃圾收集器总结

本文主要介绍了JVM中的垃圾回收器,主要包括串行回收器、并行回收器以及CMS回收器、G1回收器。他们各自都有优缺点,通常来说你需要根据你的业务,进行基于垃圾回收器的性能测试,然后再做选择。下面给出配置回收器时,经常使用的参数:

-XX:+UseSerialGC:在新生代和老年代使用串行收集器

-XX:+UseParNewGC:在新生代使用并行收集器

-XX:+ UseParallelGC:新世代のパラレル・リカバリ・コレクターを使用して、より多くの注目のスループット

-XX:+ UseParallelOldGC:パラレルコレクターを使用しての古い回復

-XX:ParallelGCThreads:ガベージコレクションのために使用されるスレッドの数を設定します。

-XX:+ UseConcMarkSweepGCを:新世代は、CMS +歳のシリアルコレクタを使用して、パラレルコレクタを使用して

-XX:ParallelCMSThreads:CMSのスレッド数を設定します

-XX:+ UseG1GC:G1ガベージコレクタを有効にします

おすすめ

転載: www.cnblogs.com/bigben0123/p/11365070.html