JVMのガベージコレクションとメモリ割り当て戦略

最終的に自動メモリ管理に提唱したJavaテクノロジー・システムは、自動化されている二つの問題を解決するために帰することができます。

  • メモリオブジェクトを割り当てるには
  • オブジェクトに割り当てられたメモリを再利用

メモリアーキテクチャ図ヒープ領域(JDK1.8永久世代を除去した後、GCは新世代と旧地区のスタックのための唯一の責任がある)
ここに画像を挿入説明
エデン地区(エデンの園が導入配分戦略の背後にあるすべてのオブジェクトの起源、意味のあります、 FromフィールドとToように命名理由を理解するより多くの時間)は、2つのサバイバル領域(Survivor領域)です。

関連チューニングパラメータ:

  • -XX:SurvivorRatio:エデンとサバイバー比、デフォルト8:1
  • -XX:NewRatio:私たちには、図2に示すようによう新旧世代のサイズ比は、そのような2を取るように、それは昔のスペースは、二回新世代れるのです。
  • -Xms / -Xmm:チーフヒープメモリサイズ-Xmsが最大初期値を設定し、-Xmmは、動的に拡張可能セット。

まず、ガベージコレクションの方針

 
主に以下の二つのガベージコレクションポリシー:

  • マイナーGC新世代の回復、死んで、そのために向けたオブジェクトの生存期間の新世代は、機能を備えた、非常に短いため、生の夜マイナーGCがされます頻繁に行われ実装のペースは、一般的に、比較的になります速いです(使用してコピーアルゴリズムを
  • フルGCリサイクル古い年と新しい世代、したがって、その者の旧生存の長尺物、フルGCはほとんど強制しない実行速度マイナーGCよりは遅いがたくさん。(使用したマーク-スイープまたはマーク-照合アルゴリズム

私はいくつかの写真、私たちは議論を容易にするために、いくつかの仮定を行うプロセスマイナーGC、について簡単なプレゼンテーションを描きました:

  • 新しいオブジェクトはエデンに割り当てられています
  • 二つサバイバー領域のサイズの比率が領域はエデン1:8が、図にプロットされている便宜上サイズ比は正確ではありません
  • (あなたが知っているとき、これは後で割り当てポリシーに導入された)領域割当ての保証は発生しません
  • (あなたが知っているとき、これは後で割り当てポリシーに導入された)新世代の老後のしきい値に3歳昇格しました

注2つのサバイバー領域およびロゴにから、次の図は、忘れるために私を描いて、前後に交換し、本当に変更するのが面倒で、奇妙なトラブル、あなたが謝罪するホールドを教えています...

私たちは今のプログラムが実行されていると仮定し、これは、任意のノードのGCは、オブジェクトがメモリが割り当てられることに遭遇した時に前に発生しましたが、エデン・スペースの不足していません。

以下

ここに画像を挿入説明
この時点でトリガーマイナーGC、生き残ったコピーオブジェクトサバイバーに、すべてのオブジェクトエデンエリアの後にクリーンアップします。また、マイナーGCを超えるのキャリーのために、オブジェクトの生存、年齢が0から1つのまでの図の番号に対応する、(1年間人間の世界と同等のマイナーGC)歳を増すことがありますので、
ここに画像を挿入説明
プログラムと実行中に、エデン領域が再び満たされている
ここに画像を挿入説明
。この時点で、再びマイナーGCをトリガし、それはサバイバーエリアから地域エデンますでしょう図中に(スペアサバイバーに別の領域にコピーされたオブジェクトを生きます。サバイバー)は、その後、すべてのオブジェクトエデン面積のとサバイバー領域から取り除きます。

次の

後に、任意の場所を、しかしサバイバー領域に上の図は、2歳のオブジェクトがまだ生きている持って、我々は仮定の冒頭で述べた、3歳の新世代は、古い時代のアイデンティティに昇進しました、このオブジェクトは、他のプロセス上で、旧宇宙の年に移動されます。

ここに画像を挿入説明
後にマイナーGC
ここに画像を挿入説明

フルGCのトリガ条件

エデンスペースがいっぱいになったときの条件は、非常にシンプルなトリガマイナーGCについては、それはマイナーGCをトリガします。フルGCは、以下の条件が比較的複雑です。

1.コールにSystem.gc()

ただ、フルGCを実行する仮想マシンをお勧めしますが、必ずしもそうではない、真の仮想マシンが実行します。この方法で使用するために推奨されるが、仮想マシンのメモリ管理をさせません。

スペースの2歳の不足

ように古いの歳に直接シーン歳、長命オブジェクトにラージオブジェクトのための共通スペースの不足と。

フルGCは、上記の原因を避けるために、あまりにも大きなオブジェクトや配列を作成しないように試してみてください。また、あなたは、-Xmnパラメータによって大きな仮想マシンの新しい世代のサイズを調整することができ、オブジェクトが新しい世代にアウト可能な限り回収されるように、古い時代を入力しないでください。また、-XXことができます:マルチの新世代内のオブジェクトは、いくつかの時間のために生き残るようMaxTenuringThresholdは、昔のに大きなオブジェクトを転送します。

3.スペースの割り当てを保証失敗

使用复制算法的 Minor GC 需要老年代的内存空间作担保,如果担保失败会执行一次 Full GC。

4. JDK 1.7 及以前的永久代空间不足

在 JDK 1.7 及以前,HotSpot 虚拟机中的方法区是用永久代实现的,永久代中存放的为一些 Class 的信息、常量、静态变量等数据。

当系统中要加载的类、反射的类和调用的方法较多时,永久代可能会被占满,在未配置为采用 CMS GC 的情况下也会执行 Full GC。如果经过 Full GC 仍然回收不了,那么虚拟机会抛出 java.lang.OutOfMemoryError。

为避免以上原因引起的 Full GC,可采用的方法为增大永久代空间或转为使用 CMS GC。

这也是为什么 JDK1.8 之后要使用元空间替代永久代的原因(降低 Full GC 的频率)。

5. Concurrent Mode Failure

执行 CMS GC 的过程中同时有对象要放入老年代,而此时老年代空间不足(可能是 GC 过程中浮动垃圾过多导致暂时性的空间不足),便会报 Concurrent Mode Failure 错误,并触发 Full GC。

 

二、内存分配策略

 

1. 对象优先在 Eden 分配

大多数情况下,对象在新生代的 Eden 区上分配(所以取名叫 Eden,伊甸园,所有对象的起源,但在 JVM 内存分配策略中,只能说是大多数对象在此出生),当 Eden 空间不够时,发起 Minor GC。
 

2. 大对象直接进入老年代

大对象是指需要连续内存空间的对象,最典型的大对象是那种很长的字符串以及数组。

经常出现大对象会提前触发垃圾收集以获取足够的连续空间分配给大对象。

相关性能调优参数:-XX:PretenureSizeThreshold,大于此值的对象直接在老年代分配,避免在 Eden 和 Survivor 之间的大量内存复制。

 

3. 长期存活的对象进入老年代

オブジェクトカウンタ用に定義された年齢、オブジェクトがエデンで生まれ、まだ生きマイナーGC後、サバイバーに移動しますた、1歳の年齢は、古い時代に15歳のデフォルトを移動し、その後、一定の年齢に、増加しました。

関連チューニングパラメータ: -XX:MaxTenuringThresholdがしきい値年齢を定義するために使用されます。
 

前記移動物体決意年齢

仮想マシンは、サバイバーで同じ年齢の合計が熟成以上対象年齢に等しいスペースサバイバーの半分のサイズよりも大きいすべてのオブジェクトは、なし、古い年に直接行くことができるならば、オブジェクトの年齢要件は、MaxTenuringThresholdの歳のプロモーションの前に満たされなければならない、常にではありません要件の年齢MaxTenuringThresholdまで待ちます。
 

スペース割り当て保証

条件が満たされた場合、それが発生する前にマイナーGC、古い仮想マシンの最大利用可能な連続スペースが総容量の新世代内のすべてのオブジェクトよりも大きいかどうかを最初のチェックは、その後、マイナーGCは、それが安全であることを確認することができます。

、その後、仮想マシンは、セキュリティの失敗を許可するかどうかの値HandlePromotionFailureを表示するように設定されていない場合は、許可されている場合には、平均のサイズ古いオブジェクトへの以前のプロモーションよりも大きな古いの最大利用可能な連続スペースが存在する場合は、マイナーGCを実施しようとするかどうかをチェックしていきます; 600未満またはHandlePromotionFailureがリスクを取ることを許可されていない場合、それは完全なGCを実施しなければなりません。

おすすめ

転載: blog.csdn.net/u013568373/article/details/94376999