まだJavaのガベージコレクションのアルゴリズム1のJavaガベージコレクションアルゴリズムは本当に死んだのJava仮想マシンのオブジェクトの深い理解のJavaのJava仮想マシンのメモリ領域の深い理解

Javaのガベージコレクションアルゴリズム

 ガベージコレクションのアルゴリズムの実現には、手続きの詳細の数が多いと、各プラットフォーム用の仮想メモリの操作方法と同じではないので、ブログでの議論のマルチアルゴリズムは、しかし、単に導入アイデアやいくつかのアルゴリズムの開発に関与したよう。

  関連読書:

  1、JavaのJava仮想マシンのメモリ領域の深い理解

  2、まだ本当に死んJava仮想マシンのオブジェクトの深い理解

 

  1、マーク - スイープアルゴリズム

  明確なアルゴリズムは、そのオブジェクトをマークするために第2段階でマーク「マーク」及び「クリア」に分割されて回収タグが完了した後、オブジェクトをラベル付けされる、回収する必要がある。以下に示すように:

  このアルゴリズムの利点は、オブジェクトが移動操作を受ける必要がないことであり、操作対象が生存するだけでなく、より高い効率で目的の場合に生存率は非常に高いが、図ビューのオブジェクトのシミュレーションからの結果は、後に回収されています、使用可能なメモリは、メモリの断片化の多くを引き起こして、連続ますが断続的ではありません。連続なので、仮想マシンのメモリ空間の新しいラージオブジェクトの割り当てに、時間に必要なメモリ空間は、ラージオブジェクトを格納することがあり、ガベージコレクションのアクションをトリガーする、保存するのに十分な連続した空き領域を見つけられないことがあり、実際の内側に空きスペースがたくさんあるが、それは連続していません。

  2、複製アルゴリズム

  コピーアルゴリズムは領域の同じサイズの2つに記憶され、それらの各々が使用されます。このメモリブロックの振れは、このメモリは、メモリ内の他のライブオブジェクトにもコピーされます場合は、このメモリは、空にされます。被写界の低い生存率で、このアルゴリズムは、ガベージコレクションの全メモリ領域の半分だけ、そのような新世代として、高効率であり、メモリの断片化の状況は移動せず、ガベージコレクションの間に発生していません単にポインタを移動するオブジェクトは、単純で、高い動作効率を達成することができます。あなたが唯一の北の村の半分を使用することができるので、作業効率は、方法の典型的な時間のためのスペースを持っている上のスペースの無駄に基づいて構築されています。次のように概略的なアルゴリズムは次のとおりです。

  

  现在商用的jvm中都采用了这种算法来回收新生代,因为新生代的对象基本上都是朝生夕死的,存活下来的对象约占10%左右,所以需要复制的对象比较少,采用这种算法效率比较高。hotspot版本的虚拟机将堆(heap)内存分为了新生代和老年代,其中新生代又分为内存较大的Eden区和两个较小的survivor区。当进行内存回收时,将eden区和survivor区的还存活的对象一次性地复制到另一个survivor空间上,最后将eden区和刚才使用过的survivor空间清理掉。hotspot虚拟机默认eden和survivor空间的大小比例为8:1,也就是每次新生代中可用内存空间为整个新生代空间的90%(80%+10%),只会浪费掉10%的空间。当然,98%的对象可回收只是一般场景下的数据,我们没有办法保证每次回收都只有不多于10%的对象存活,当survivor空间不够用时,需要依赖于其他内存(这里指的是老年代)进行分配的担保。

  3、标记-整理算法

  复制算法在对象存活率较高的情况下就要进行较多的对象复制操作,效率将会变低。更关键的是,如果你不需要浪费50%的空间,就需要有额外的空间进行分配担保,用以应对被使用的内存中所有对象都100%存活的极端情况,所以在老年代一般不能直接选用这种办法。

  根据老年代的特点,有人提出了标记-整理的算法,标记过程仍然与标记-清楚算法一样,但后续步骤不是直接将可回收对象清理掉,而是让所有存活的对象都向一端移动,然后直接清理掉端边界以外的内存,算法示意图如下:

  4、分代收集算法

  分代收集算法将heap区域划分为新生代和老年代,新生代的空间比老年代的空间要小。新生代又分为了Eden和两个survivor空间,它们的比例为8:1:1。对象被创建时,内存的分配是在新生代的Eden区发生的,大对象直接在老年代分配内存,IBM的研究表明,Eden区98%的对象都是很快消亡的。

  为了提高gc效率,分代收集算法中新生代和老年代的gc是分开的,新生代发生的gc动作叫做minor gc 或 young gc,老年代发生的叫做major gc 或 full gc。

  minor gc 的触发条件:当创建新对象时Eden区剩余空间小于对象的内存大小时发生minor gc;

  major gc 触发条件:

  1、显式调用System.gc()方法;

  2、老年代空间不足;

  3、方法区空间不足;

  4、从新生代进入老年代的空间大于老年代空闲空间;

  Eden区对象的特点是生命周期短,存活率低,因此Eden区使用了复制算法来回收对象,上面也提到复制算法的特点是在存活率较低的情况下效率会高很多,因为需要复制的对象少。与一般的复制算法不同的是,一般的复制算法每次只能使用一半的空间,另一半则浪费掉了,Eden区的回收算法也叫做"停止-复制"算法,当Eden区空间已满时,触发Minor GC,清理掉无用的对象,然后将存活的对象复制到survivor1区(此时survivor0有存活对象,survivor1为空的),清理完成后survivor0为空白空间,survivor1有存活对象,然后将survivor0和survivor1空间的角色对象,下次触发Minor gc时重复上述过程。如果survivor1区剩余空间小于复制对象所需空间时,将对象分配到老年代中。每发生一次Minor gc时,存活下来的对象的年龄则会加1,达到一定的年龄后(默认为15)该对象就会进入到老年代中。

  老年代的对象基本是经过多次Minor gc后存活下来的,因此他们都是比较稳定的,存活率高,如果还是用复制算法显然是行不通的。所以老年代使用“标记-整理”算法来回收对象的,从而提高老年代回收效率。

  总的来说,分代收集算法并不是一种具体的算法,而是根据每个年龄代的特点,多种算法结合使用来提高垃圾回收效率。

  参考资料:《深入理解Java虚拟机》

 

おすすめ

転載: www.cnblogs.com/Leo_wl/p/10988699.html