Javaのガベージコレクションと最適化

リサイクルすることができまず、メモリ

JVMのメモリ領域、プログラムカウンタ、仮想マシン・スタックとネイティブメソッドは、これらの三つの領域をスタックスレッドの作成を、民間のスレッドで、作成し、破壊し、破壊するので、回復しません。

ガベージコレクションは、注意の焦点であるヒープおよびメソッド領域リサイクル方法領域が無駄と無用のクラスの主に一定のリサイクルで、メモリ内、およびヒープの回復は、コレクションに主に対象となります。

 

第二に、それはリサイクルすることができたときに

通常、オブジェクトは、もはやオブジェクトに代わって、参照されていない回収することができます。オブジェクトを再利用できるかどうかを判断することができます2つのアルゴリズムがあります。

1、参照カウントアルゴリズム

このアルゴリズムは、オブジェクトは、オブジェクトの参照カウントによって参照されているかどうかを決定することです。基準故障カウンタがデクリメントされるたびに、オブジェクトが参照されるたびに、参照カウンタが1だけ増加されます。

オブジェクト参照カウンタの値が0である場合、それは、オブジェクトがもはや参照されないことを示し回収することができます。

参照カウントアルゴリズムは、単純な達成するが、高い効率を求めたが、円形の基準オブジェクトとの間の相互に問題があるれています。

2、到達可能性解析アルゴリズム

GCのルーツオブジェクトへのすべての参照のルートです。ガベージコレクションは、それが回復することができ、このオブジェクトによって証明されるように、オブジェクトは、任意の基準GCルーツ・チェーンに接続されていないダウンGC根から探索を開始するとき。

現時点では、アルゴリズムのHotSpot仮想マシンがあります。

2.1、GCルーツ・オブジェクト

オブジェクト参照Java仮想マシン・スタック、JNIネイティブメソッドスタック内の参照オブジェクト、メソッドゾーンクラス静的プロパティ、定数オブジェクト

 

前述のアルゴリズムは、物体を回収することができるかどうかを参照することによって決定されます。JDK 1.2、Javaのコンセプトが展開された参考文献の後、参照は以下の4つのカテゴリに分類されます。

 

第三に、コレクションアルゴリズム

 

 

 

第四に、リサイクル/タイプ

 

 

 IDのような、ガベージコレクタのタイプを設定するなど、jmapの-heapプロセスによってJVMの構成情報を確認することができます。

 

 

 

五、GCのパフォーマンスメトリック

吞吐量:这里的吞吐量是指应用程序所花费的时间和系统总运行时间的比值。我们可以按照这个公式来计算 GC 的吞吐量:系统总运行时间 = 应用程序耗时 +GC 耗时。如果系统运行了 100 分钟,GC 耗时 1 分钟,则系统吞吐量为 99%。

停顿时间:指垃圾收集器正在运行时,应用程序的暂停时间。对于串行回收器而言,停顿时间可能会比较长;而使用并发回收器,由于垃圾收集器和应用程序交替运行,程序的停顿时间就会变短,但其效率很可能不如独占垃圾收集器,系统的吞吐量也很可能会降低。

 

六、查看 & 分析 GC 日志

首先,我们需要通过 JVM 参数预先设置 GC 日志,通常有以下几种 JVM 参数设置:

-XX:+PrintGC 输出 GC 日志
-XX:+PrintGCDetails 输出 GC 的详细日志
-XX:+PrintGCTimeStamps 输出 GC 的时间戳(以基准时间的形式)
-XX:+PrintGCDateStamps 输出 GC 的时间戳(以日期的形式,如 2013-05-04T21:53:59.234+0800)
-XX:+PrintHeapAtGC 在进行 GC 的前后打印出堆的信息
-Xloggc:../logs/gc.log 日志文件的输出路径

 

如果GC日志非常大,可以用GCViewer工具打开日志文件,图形化界面查看整体的 GC 性能,如下图所示:

也可以用GCeasy工具,并且还可以将日志文件压缩之后,上传到 GCeasy 官网即可看到非常清楚的 GC 日志分析结果

 

七、回收调优

1. 降低 Minor GC 频率

Eden区存活的对象数量小,可以通过增大新生代空间来降低 Minor GC 的频率。

通常情况下,由于新生代空间较小,Eden 区很快被填满,就会导致频繁 Minor GC,因此我们可以通过增大新生代空间来降低 Minor GC 的频率。

可能你会有这样的疑问,扩容 Eden 区虽然可以减少 Minor GC 的次数,但不会增加单次 Minor GC 的时间吗?如果单次 Minor GC 的时间增加,那也很难达到我们期待的优化效果呀。

如果在堆内存中存在较多的长期存活的对象,此时增加年轻代空间,反而会增加 Minor  GC 的时间。如果堆中的短期对象很多,那么扩容新生代,单次 Minor GC 时间不会显著增加。因此,单次 Minor GC 时间更多取决于 GC 后存活对象的数量,而非 Eden 区的大小。

2、降低 Full GC 的频率

2.1、减少创建大对象

2.2、增大堆内存空间

2.3、选择合适的 GC 回收器

垃圾收集器的种类很多,我们可以将其分成两种类型,一种是响应速度快,一种是吞吐量高。通常情况下,CMS (Concurrent Mark Sweep)和 G1 回收器的响应速度快,Parallel Scavenge 回收器的吞吐量高

 

ps1:首先cms在1.9已经被标记为废弃,主要原因在于标记清除下的悬浮内存,导致内存空间碎片化,进而导致fullGC的发生。不过其并行执行垃圾回收的性能还是值得认可的,至少1.9后主推的G1在常规情况下也是不如它的效率好的。

 

ps2:G1与CMS的优势在于以下几点:

1、并行与并发:G1能够更充分利用多CPU、多核环境运行

2、分代收集:G1虽然也用了分代概念,但相比其他收集器需要配合不同收集协同工作,但G1收集器能够独立管理整个堆

3、空间管理:与CMS的标记一清理算法不同,G1从整体上基于标记一整理算法,将整个Java堆划分为多个大小相等的独立区域(Region),这种算法能够在运行过程中不产生内存碎片

4、可预测的停顿:降低停顿时间是G1和CMS共同目标,但是G1追求低停顿外,还能建立可预测的停顿时间模型,能让使用者明确指定一个长度为M毫秒的时间片段内,消耗在垃圾收集器上的时间不得超过N毫秒。

eg:通过XX:MaxGCPauseMillis =500可以设置full gc 稳定在500ms以内

 

ps3:oracle一些1.9 10 11 12的特性都有以补丁的方式落到1.8。所以1.8还是比较安全实用的

 

おすすめ

転載: www.cnblogs.com/jetqiu/p/11689611.html