JVM ランタイム メモリ生成構造

JVM ランタイム メモリ生成構造

Java アプリケーションの場合、Java ヒープは仮想マシンによって管理されるメモリの最大の部分です。 Java ヒープはすべてのスレッドで共有されるメモリ領域であり、仮想マシンの起動時に作成されます。このメモリ領域の唯一の目的はオブジェクト インスタンスを格納することであり、すべてのオブジェクト インスタンスにここでメモリが割り当てられます。

Java ヒープは、ガベージ コレクターによって管理されるメモリ領域です。メモリ回復の観点から見ると、ほとんどのガベージ コレクターは世代別コレクション理論に基づいて設計されているため、Java ヒープには「新しい世代」、「古い世代」、「永久世代」、「Eden 空間」、「Survivor 空間から」、「Survivor 空間へ」などの領域が頻繁に出現します。これらの領域分割は、特定の Java 仮想マシン実装の固有のメモリ レイアウトではなく、一部のガベージ コレクターの一般的な特性または設計スタイルにすぎず、Java 仮想マシン仕様における Java ヒープに関する公式の定義でもありません。たとえば、Shenandoah と ZGC は世代をサポートしていません。

JDK 1.7 世代構造

JDK 1.7 以前では、ヒープ領域は新しい世代、古い世代、永続的な世代の 3 つの部分に分かれています。そして、新しい世代はエデンエリアと 2 つのサバイバーエリアに分割されます。下の図に示すように


JDK 1.8 世代構造

JDK 1.8 以降では、永続世代はヒープ領域から削除されます。永続世代が削除される理由については、次のドキュメントを参照してください: http://openjdk.java.net/jeps/122。主な理由は次のとおりです。これは、Hotspot と JRockit 仮想マシンの融合です。 JRockit クライアントは、永続的な世代を構成する必要はありません (JRockit には永続的な世代がないため)。また、永続的な世代を構成しないのが通例です。メタスペースを追加すると、クラスのロードに必要なメモリ領域が解決され、メタスペースはデフォルトで自動的に拡張されます。これにより、メモリ オーバーフローの可能性が軽減されます。ヒープ領域から永続世代が削除された後、ヒープ領域の構造は次のようになります。

ランタイム データ領域の構造を次の図に示します。


G1コレクター

G1 は、新世代と旧世代間の物理的な空間分割を解除します。代わりに、G1 アルゴリズムはヒープ領域を複数の領域に分割しますが、これは依然として世代別コレクターです。ただし、これらの領域の一部には新しい世代が含まれており、新しい世代のガベージ コレクションでは、すべてのアプリケーション スレッドを一時停止して、生き残ったオブジェクトを古い世代または Survivor スペースにコピーする方法が引き続き使用されます。古い世代も多くの領域に分割されており、G1 コレクターはオブジェクトをある領域から別の領域にコピーすることでクリーンアップを完了します。つまり、通常の処理中に、G1 はヒープ (少なくともヒープの一部) の圧縮を完了するため、CMS メモリの断片化の問題は発生しません。

G1には、Humongousエリアと呼ばれる特別なエリアもあります。オブジェクトがパーティション容量の 50% 以上を占める場合、G1 コレクターはそれを巨大オブジェクトと見なします。これらの巨大オブジェクトは、デフォルトでは古い世代に直接割り当てられますが、寿命の短い巨大オブジェクトの場合は、ガベージ コレクターに悪影響を及ぼします。この問題を解決するために、G1 は巨大なオブジェクトを保管するために使用される Humongous 領域を分割します。巨大なオブジェクトが 1 つの H 領域に収まらない場合、G1 はそれを保存するために連続する H パーティションを探します。連続した H 領域を見つけるために、Full GC を開始する必要がある場合があります。

オブジェクトメモリの割り当て

オブジェクト メモリの割り当てプロセスは次のとおりです。

メモリ割り当てルールの具体的な説明は次のとおりです。

オブジェクトはまずEden領域に割り当てられます

ほとんどの場合、オブジェクトは新世代の Eden 領域に割り当てられます。 Eden 領域に割り当てるための十分なスペースがない場合、仮想マシンはマイナー GC を開始します。 HotSpot 仮想マシンは、コレクター ログ パラメータ -XX:+PrintGCDetails を提供します。これは、ガベージ コレクションが発生したときにメモリ回復ログを印刷し、プロセスが終了したときに各領域の現在のメモリ割り当てステータスを出力するように仮想マシンに指示します。テストコード:

  1. /**
  2. * -XX:+PrintGC詳細
  3. */
  4. パブリッククラスGCTest{
  5.  
  6. 公共 静的void main(String[] args) {
  7. byte[] allcation2 = 新しいbyte[8000 * 1024];
  8. }
  9. }

出力

  1. ヒープ
  2. PSYoungGen 合計 38400K、使用済み 11353K [0x0000000795580000、0x0000000798000000、0x00000007c0000000)
  3. エデンスペース33280K、34% 使用済み [0x0000000795580000,0x00000007960966f8,0x0000000797600000)
  4. から スペース5120K、使用率 0% [0x0000000797b00000、0x0000000797b00000、0x0000000798000000)
  5.    スペース5120K、使用率 0% [0x0000000797600000、0x0000000797600000、0x0000000797b00000)
  6. ParOldGen 合計 87552K、使用済み 0K [0x0000000740000000、0x0000000745580000、0x0000000795580000)
  7. オブジェクトスペース87552K、使用率 0% [0x0000000740000000,0x0000000740000000,0x0000000745580000)
  8. メタスペース使用 3017K、容量 4556K、コミット済み4864K、予約済み 1056768K
  9. クラススペース使用済み 319K、容量 392K、コミット済み512K、予約済み 1048576K

メモリ空間の分布から、allocation2 が eden 領域に割り当てられていることがわかります。

大きなオブジェクトは直接古い世代に送られます

ラージ オブジェクトとは、大量の連続したメモリ領域を必要とする Java オブジェクト (文字列や配列など) を指します。 JVM パラメータ -XX:PretenureSizeThreshold を使用すると、大きなオブジェクトのサイズを設定でき、設定された値より大きいオブジェクトは古い世代に直接割り当てられ、若い世代には入らないように指定できます。このパラメータは、Serial および ParNew コレクターでのみ有効です。たとえば、JVM パラメータ: -XX:PretenureSizeThreshold=1000000 (ユニット直接) -XX:+UseSerialGC を設定すると、上記の最初のプログラムを実行すると、大きなオブジェクトが直接古い世代に移動されることがわかります。これを行う目的は、Eden 領域と 2 つの Survivor 領域間でのコピーを回避することです。コピーが行われると、大量のメモリ コピー操作が発生します。

長寿命オブジェクトは古い世代に入ります

HotSpot 仮想マシンのほとんどのコレクターは、世代別コレクションを使用してヒープ メモリを管理します。メモリがリサイクルされるとき、どの残存オブジェクトを新しい世代に配置し、どの残存オブジェクトを古い世代に配置するかを決定できる必要があります。これを行うために、仮想マシンは各オブジェクトのオブジェクト年齢カウンタを定義し、それをオブジェクト ヘッダーに格納します。オブジェクトは通常、エデン領域で生成されます。最初のマイナー GC 後もオブジェクトが存続し、Survivor スペースに収容できる場合、オブジェクトは Survivor スペースに移動され、オブジェクトの年齢は 1 年に設定されます。オブジェクトがサバイバー領域でマイナー GC を生き延びるたびに、そのオブジェクトの年齢は 1 年増加します。年齢が一定のレベル (デフォルトは 15) に達すると、古い世代に昇格されます。古い世代に昇格されるオブジェクトの年齢しきい値は、-XX:MaxTenuringThreshold パラメータを使用して設定できます。

動的オブジェクト年齢判定

さまざまなプログラムのメモリ条件に適切に適応するために、HotSpot 仮想マシンでは、オブジェクトを古い世代に昇格させる前に、必ずしもオブジェクトの年齢が -XX:MaxTenuringThreshold に達する必要はありません。 Survivor スペース内の同じ年齢のすべてのオブジェクトのサイズの合計が Survivor スペースの半分より大きい場合、その年齢以上のオブジェクトは、-XX:MaxTenuringThreshold で必要な年齢まで待たずに、直接古い世代に入ることができます。

スペース割り当て保証

マイナー GC が発生する前に、仮想マシンはまず、古い世代で使用可能な連続領域の最大サイズが、新しい世代のすべてのオブジェクトの合計領域よりも大きいかどうかを確認する必要があります。

この記事はWeChatの公開アカウント「運営保守開発ストーリー」から転載したものです。

【編集者のおすすめ】

  1. 鴻蒙公式戦略協力と建設——HarmonyOS技術コミュニティ
  2. クラウド内のコンテナ: どのような選択肢がありますか?
  3. 5Gメッセージングは​​開発段階に入る
  4. ドメインハイジャックとは何ですか?ドメイン名のハイジャックに対処する方法
  5. プログラミングを独学する場合、まずどの言語を選べばいいでしょうか?
  6. ウェブクローラーの完全な歴史

<<:  Pythonの仮想環境は非常に簡単です。これを読めばすぐにわかるでしょう。

>>:  スマートトラベルに焦点を当てたJDリテールクラウドのJDミニプログラムは、人と車のためのフルシナリオエコシステムの構築に役立ちます。

推薦する

A5最適化チーム:ウェブサイトURL構造計画事例分析レポート

ウェブマスター、あなたのウェブサイトはなぜ含まれていないのですか?コンテンツの質は十分に高く、外部リ...

ウェブサイトマーケティングはユーザーのニーズに基づいて行い、革新を追求する必要がある

今日、私はギークパークイノベーションカンファレンスでのQihoo 360 CEO の周紅毅氏のスピー...

VMware CEOがクラウドコンピューティング開発計画を議論するため初めて中国を訪問

2010 年 3 月 5 日の午後、VMware 社長兼 CEO のポール マリッツは中国訪問中に北...

おすすめ: Vultr-12月の年間20ドルクーポンコード

vultr.com は 12 月に人気の割引コード、SSDVPS を提供しています。このコードを使用...

検索サプライチェーンのソースとして、ゴミ製品と良質製品どちらを生産していますか?

日常生活では、生産サプライチェーンと電子商取引サプライチェーンについて最もよく耳にします。同様に、巨...

ウェブサイトの最適化と検索エンジンの最適化の関係

ウェブサイトの最適化には、ユーザーの最適化、検索エンジンの最適化、ウェブサイトの運用と保守の最適化と...

JavaScript: ルールを全て破る 間違ったことが役に立つかもしれない

北京時間のこの日の早朝、 Twitter のフロントエンド エンジニアである Angus Crol ...

ブランドウェブサイトのフレンドリーなリンク方法からどのような反映が得られるでしょうか?

フレンドリーリンクについての記事はたくさんあるので、今日はその詳細についてお話します。これが、大規模...

あまり知られていない VMware の 6 つのトリック

[[242514]] 1. VMware が esxi ネットワーク カード ドライバーをアップグレ...

123systems - 3 年間 $34/2IP/3G メモリ/75g ハード ドライブ/3T トラフィック/4 コンピュータ ルーム

コロクロッシングが買収したブランドである123ystemsは、長い間登場していません。ホストキャット...

モバイルクライアントの売上を増やす10の方法: 携帯電話からユーザーを引き付ける

多くの企業は、ウェブサイトのトラフィックを増やし、顧客に自社製品についてより詳しく知ってもらうために...

ダブルイレブンが李佳琦に憑依

李佳琦とヴィヤが一晩で200億元相当の商品を販売したのを見て、ネットユーザーたちは数字に目がくらみ、...

小米のダブル12の売上高は71.5億元、Kingsoft Cloudは再びバックエンド保証を成功裏に完了

最近、Xiaomiは正式にダブル12の最終戦レポートを発表しました。これは、今年の2つの主要な電子商...

究極の最適化には、サイト内外の同時改善が必要

SEO 業界の敷居がどんどん低くなるにつれて、競争もますます激しくなっています。では、このような激し...