JVMはオブジェクトが死んだと判断し、GCリサイクルを検証します。

JVMはオブジェクトが死んだと判断し、GCリサイクルを検証します。

[[377367]]

この記事はWeChatの公開アカウント「bugstack」から転載したもので、著者はXiao Fu Geです。この記事を転載する場合は、bugstack の公開アカウントにご連絡ください。

目次

  • 1. はじめに
  • 2. 面接の質問
  • 3. まずガベージコレクションを検証する
  • 4. JVM ガベージ コレクション知識フレームワーク
    • 1. 被験者が死亡しているかどうかを判断する
    • 2. ガベージコレクションアルゴリズム
    • 3. ガベージコレクター
  • V. 結論
  • 6. シリーズのおすすめ

1. はじめに

自分の価値を高めることはどれほど重要ですか?

私は浮き沈みを経験し、男性も女性も見てきました。時間が経つにつれ、永遠に続くものは何もありません!

この電車では降りる人もいれば乗る人もいます。他人があなたに付けたレッテルやコメントによる印象は、この列車に関する物語に過ぎません。人は成長し、蓄積し、落ち着いたときにのみ、自分自身の運転手になる機会を得ることができます。

ある年齢になると理解できないかもしれませんが、ある日忙しくなくなったら、自分の進むべき道や歩みについて考えてみるといいでしょう。これらがあなたが望むものであるかどうか確認してください。それがあなたの望むものなら、なぜ不幸そうな顔をしているのですか?

良い!進み続けて、なりたい自分に向かって進みましょう!

2. 面接の質問

ご連絡ありがとうございます!昼にお腹いっぱい食べた後、空想にふけり始めました。なぜこの知識を学ぶことができないのでしょうか?私の頭には入ってこないよ!

「謝菲冰冰」:こんにちは、インタビュアーさん、質問があります。

インタビュアー:何ですか?

「ありがとう、フェイジ」:この知識は私の頭には入ってこない!

インタビュアー:これは…

「フェイジジありがとう」: 観終わったら忘れてた。見るのを忘れてた!

インタビュアー:練習はしなかったんですか?読んだだけで分かったと思って、保存しただけで理解したと思っていませんか?何も深く考えていないよ!?

「謝非機」:そうらしいですね!私たちに何ができるでしょうか?

インタビュアー:これより良い方法はありません。学ぶこと自体は退屈なことです。断片的な時間の無駄を減らし、体系的な学習にもっと時間を費やす方が良いでしょう。記録としてブログを書くにしても、検証してみると良いでしょう。

3. まずガベージコレクションを検証する

参照しないとガベージコレクションがリサイクルされるそうですが?いつリサイクルされますか?どのようにリサイクルされるのですか?

実際の例を見なければ、理系の学生がこの種の知識を受け入れるのは難しい場合がよくあります。私も同じで、見ることができたら一番いいです。コードは数学的論理の具体的な実装です。実装プロセスなしで答えだけを見ても意味がありません。

「テストコード」

  1. パブリッククラス ReferenceCountingGC {
  2.  
  3. パブリックオブジェクトインスタンス = null ;
  4. プライベート静的最終int _1MB = 1024 * 1024;
  5. /**
  6. * このメンバープロパティの唯一の目的は、メモリを占有して、リサイクルされたかどうかをGCログで明確に確認できるようにすることです。
  7. */
  8. プライベートbyte[] bigSize = 新しいbyte[2 * _1MB];
  9.  
  10. 公共 静的void main(String[] args) {
  11. テストGC();
  12. }
  13.  
  14. 公共 静的void testGC() {
  15. ReferenceCountingGC objA = 新しいReferenceCountingGC();
  16. ReferenceCountingGC objB = 新しいReferenceCountingGC();
  17. objA インスタンス = objB;
  18. objB インスタンス = objA;
  19. objA = null ;
  20. objB = null ;
  21. // この行で GC が発生すると仮定すると、objA と objB はリサイクルできますか?
  22. システム.gc();
  23. }
  24.  
  25. }

この例は、「Java 仮想マシンの詳細な理解」の参照カウント アルゴリズムの章から引用したものです。

この例の結果は、相互に参照しているが null に設定されている 2 つのオブジェクトが GC によってリサイクルされるかどうかを示しています。参照カウンター アルゴリズムのみに従うと、これら 2 つのオブジェクトのカウント識別子は 0 にならず、リサイクルできません。しかし、それはリサイクルされたのでしょうか?

ここでは、まず jvm ツール命令 jstat を使用して監視します。監視プロセスでは手動でコードを入力する必要があり、時間がかかるため、Thread.sleep(55000); でスリープします。 testGC() を呼び出す前に。コードを起動したら、以下の命令を実行します。

  1. E:\itstack\git\github.com\インタビュー>jps -l
  2. 10656
  3. 88464
  4. 38372 org.itstack.interview.ReferenceCountingGC
  5. 26552 sun.tools.jps.Jps
  6. 110056 org.jetbrains.jps.cmdline.ランチャー
  7.  
  8. E:\itstack\git\github.com\インタビュー>jstat -gc 38372 2000
  9. S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT
  10. 10752.0 10752.0 0.0 0.0 65536.0 6561.4 175104.0 0.0 4480.0 770.9 384.0 75.9 0 0.000 0 0.000 0.000
  11. 10752.0 10752.0 0.0 0.0 65536.0 6561.4 175104.0 0.0 4480.0 770.9 384.0 75.9 0 0.000 0 0.000 0.000
  12. 10752.0 10752.0 0.0 0.0 65536.0 6561.4 175104.0 0.0 4480.0 770.9 384.0 75.9 0 0.000 0 0.000 0.000
  13. 10752.0 10752.0 0.0 0.0 65536.0 6561.4 175104.0 0.0 4480.0 770.9 384.0 75.9 0 0.000 0 0.000 0.000
  14. 10752.0 10752.0 0.0 0.0 65536.0 6561.4 175104.0 0.0 4480.0 770.9 384.0 75.9 0 0.000 0 0.000 0.000
  15. 10752.0 10752.0 0.0 0.0 65536.0 6561.4 175104.0 0.0 4480.0 770.9 384.0 75.9 0 0.000 0 0.000 0.000
  16. 10752.0 10752.0 0.0 0.0 65536.0 6561.4 175104.0 0.0 4480.0 770.9 384.0 75.9 0 0.000 0 0.000 0.000
  17. 10752.0 10752.0 0.0 1288.0 65536.0 0.0 175104.0 8.0 4864.0 3982.6 512.0 440.5 1 0.003 1 0.000 0.003
  18. 10752.0 10752.0 0.0 0.0 65536.0 437.3 175104.0 1125.5 4864.0 3982.6 512.0 440.5 1 0.003 1 0.012 0.015
  19. 10752.0 10752.0 0.0 0.0 65536.0 437.3 175104.0 1125.5 4864.0 3982.6 512.0 440.5
  • S0C、S1C、第1および第2の生存領域のサイズ
  • S0U、S1U、第 1 および第 2 のサバイバー スペースの使用サイズ
  • EC、EU、エデンの大きさと利用
  • 旧世代の OC、OU、サイズ、使用状況
  • MC、MU、メソッド領域のサイズと使用
  • CCSC、CCSU、圧縮クラスのスペース サイズと使用量
  • YGC、YGCT、若い世代のガベージコレクションの回数と時間
  • FGC、FGCT、旧世代のガベージコレクションの回数と時間
  • GCT、ガベージコレクションの合計時間

注: 次の 3 行 (S1U = 1288.0、GCT = 0.003) を見ると、ガベージ コレクションがすでに実行されていることがわかります。

次に、別の方法でテストしてみましょう。起動したプログラムで、GC 印刷パラメータを追加し、GC 変更結果を確認します。

  1. -XX:+PrintGCDetails は、各 GC の回復ステータスを出力します。プログラムの実行後、ヒープスペースのメモリ情報(メモリオーバーフローを含む)を出力します。
  2. -XX:+PrintHeapAtGC は各 GC の前後のメモリ状況を出力します
  3. -XX:+PrintGCTimeStamps は、各 GC 間隔のタイムスタンプを出力します。フルGC は、毎回、新しい世代、古い世代、およびスペース全体を統合してリサイクルします。システムは回避すべきである
  4. -XX:+TraceClassLoading はクラスのロードステータスを出力します
  5. -XX:+PrintClassHistogram は各クラスインスタンスのメモリ使用量を出力します
  6. -Xloggc:/Users/xiaofuge/Desktop/logs/log.log 上記のコマンドを使用して、上記のログを指定されたファイルに出力します。
  7. -XX:HeapDumpOnOutOfMemoryError は、メモリ不足エラーのヒープ情報をダンプして分析します。

今回は、スリープ機能を削除し、次のようにパラメータ -XX:+PrintGCDetails を追加します。

テスト結果

  1. [GC (System.gc()) [PSYoungGen: 9346K->936K(76288K)] 9346K->944K(251392K)、0.0008518 秒] [時間:ユーザー=0.00 sys=0.00、実数=0.00 秒]
  2. [フルGC (System.gc()) [PSYoungGen: 936K->0K(76288K)] [ParOldGen: 8K->764K(175104K)] 944K->764K(251392K)、[メタスペース: 3405K->3405K(1056768K)​​]、0.0040034 秒] [時間:ユーザー=0.08 sys=0.00、実数=0.00 秒]
  3. ヒープ
  4. PSYoungGen 合計 76288K、使用済み 1966K [0x000000076b500000、0x0000000770a00000、0x00000007c0000000)
  5. エデンスペース65536K、3% 使用済み [0x000000076b500000、0x000000076b6eb9e0、0x000000076f500000)
  6. から スペース10752K、使用率 0% [0x000000076f500000、0x000000076f500000、0x000000076ff80000)
  7.    スペース10752K、使用率 0% [0x000000076ff80000、0x000000076ff80000、0x0000000770a00000)
  8. ParOldGen 合計 175104K、使用済み 764K [0x00000006c1e00000、0x00000006cc900000、0x000000076b500000)
  9. オブジェクトスペース175104K、使用率 0% [0x00000006c1e00000、0x00000006c1ebf100、0x00000006cc900000)
  10. メタスペース使用 3449K、容量 4496K、コミット済み4864K、予約済み 1056768K
  11. クラス使用領域376K、容量 388K、コミット済み512K、予約済み 1048576K
  • 実行結果から、メモリ回復ログを確認し、Full GC が回復されていることがわかります。
  • また、JVM はオブジェクトが生きているかどうかを判断するために参照カウンターに依存していないこともわかります。そうしないとリサイクルされません。

「この例を使って、JVM ガベージ コレクションの知識フレームワークを見てみましょう。」

4. JVM ガベージ コレクション知識フレームワーク

ガベージ コレクション (GC) は、1960 年に MIT Lisp で初めて誕生し、動的なメモリ割り当てとガベージ コレクション テクノロジを使用する最初の言語です。

ガベージ コレクターは主に、どのメモリを再利用する必要があるか、いつ再利用するか、どのように再利用するかという 3 つのことを行います。

ゴミ収集車が誕生して半世紀が経ちました。現在、動的メモリ割り当てとメモリリサイクルの技術は非常に成熟しており、すべてが「自動」段階に入ったようです。しかし、同時実行性の高いシナリオでは、メモリ オーバーフロー、リーク、GC 時間プロセスなどの問題があるかどうかを監視する必要がある場合もあります。したがって、ガベージコレクションに関する関連知識を理解し知ることは、上級プログラマーの成長にとって非常に重要です。

ガベージ コレクターのコア知識項目には、主に、オブジェクトが生きているかどうかの判断、ガベージ コレクション アルゴリズム、さまざまな種類のガベージ コレクター、およびガベージ コレクション プロセスが含まれます。下記の通りです。

図27-1 ガベージコレクタの知識フレームワーク

オリジナル画像のダウンロードリンク: http://book.bugstack.cn/#s/6jJp2icA

1. 被験者が死亡しているかどうかを判断する

1.1 参照カウンタ

  1. 各オブジェクトに参照カウンターを追加し、オブジェクトへの参照の数をカウントします。
  2. オブジェクトに対応する参照更新操作がある場合、対象オブジェクトの参照カウンターが増加または減少します。
  3. オブジェクトの参照カウンタが 0 に達すると、そのオブジェクトは無効になり、ガベージ コレクションの対象になることを意味します。

実装の観点から見ると、参照カウント方式はカウントのために余分なメモリスペースを占有しますが、実装が簡単で、判定効率が高いため、優れたアルゴリズムになります。

Microsoft COM (コンポーネント オブジェクト モデル) テクノロジ、ActionScript 3 を使用した Flash Player、Python 言語など、よく知られている参照事例もいくつかあります。

「しかし」、主流のJava仮想マシンはメモリ管理に参照技術アルゴリズムを使用しません。主な理由は、この単純なカウント方法は、相互依存性や循環参照などを扱うときに非常に複雑になるためです。使用されなくなったメモリがあるかもしれませんが、再利用できず、メモリリークが発生する可能性があります。

1.2 到達可能性分析

Java や C# などの主流言語のメモリ管理サブシステムはすべて、到達可能性分析アルゴリズムを使用して、オブジェクトが生きているかどうかを判断します。

このアルゴリズムは、GC ルートと呼ばれる一連のルート オブジェクトを開始ノード セットとして定義し、これらのノードから開始して、セットによって参照されるすべてのオブジェクトを網羅的に列挙し、それらをセット (ライブ セット) に埋め込むというものです。このプロセスでは、生きているオブジェクトのみをマークするように学習します。そのため、マークされていないオブジェクトはリサイクル可能なオブジェクトになります。

GC ルートには以下が含まれます。

  1. グローバル参照、メソッド領域内の静的オブジェクトおよび定数オブジェクトへの参照
  2. 実行コンテキスト、Java メソッド スタック フレーム内のローカル オブジェクトへの参照、JNI ハンドル オブジェクトへの参照
  3. 開始されて停止されていないJavaスレッド

2つの大きな問題

誤検知: 死んだオブジェクトが生きているものとしてマークされ、ガベージコレクションできません。メモリを少し多く消費しますが、影響は小さいです。

ネガティブなミス: 参照されたオブジェクト (使用中) はアクティブとしてマークされておらず、ガベージ コレクションされました。その結果、直接的な結果として JVM がクラッシュします。 (STWは到達可能性分析の精度を確保し、報告不足を回避できます)

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

2.1 マークスイープアルゴリズム

マークスイープ

  • 参照されていないデッドオブジェクトによって占有されている空きメモリをマークし、空きリストに記録します。
  • 新しいオブジェクトを作成する必要がある場合、メモリ管理モジュールは空きリストで空きメモリを検索し、それを新しく作成されたオブジェクトに割り当てます。
  • このクリーニング方法は実は非常にシンプルで効率的ですが、メモリの断片化が深刻すぎるという問題もあります。
  • Java 仮想マシンのヒープ内のオブジェクトは連続して分散される必要があるため、極端な場合には、合計残りメモリが十分であっても、連続したメモリ割り当てを見つける効率が低いか、メモリを割り当てられないほど深刻になります。トーキング・トムを再起動してください!
  • このタイプのアルゴリズムは CMS で使用されており、GC 一時停止時間は短いですが、アルゴリズムに欠陥があります。

2.2 マークコピーアルゴリズム

マークコピーアルゴリズム

  • 写真から、今回ガベージクリーンアップが完了した後、連続メモリスペースが大きくなっていることがわかります。
  • このメソッドは、メモリ領域を 2 つの部分に分割し、それぞれ from と to の 2 つのポインターによって管理し、from ポインターが指すメモリ領域のみを使用してメモリを割り当てます。
  • ガベージ コレクションが発生すると、生き残ったオブジェクトは to ポインターが指すメモリ領域にコピーされ、from ポインターと to ポインターが交換されます。
  • その利点は明らかで、メモリの断片化の問題を解決できることです。しかし、ヒープ領域の半分が無駄になるという他の問題も発生します。

2.3 マークコンパクトアルゴリズム

マークコンパクトアルゴリズム

  • 1974 年に、エドワード・ルーダースはマーク圧縮アルゴリズムを提案しました。マーキング プロセスはマーク スイープ アルゴリズムと同じですが、後続のオブジェクト クリーニング ステップでは、生き残ったオブジェクトが最初にメモリ空間の一方の端に移動され、次にもう一方のメモリ空間がクリーンアップされます。
  • このアルゴリズムはメモリの断片化の問題を解決できますが、圧縮アルゴリズムのパフォーマンスのオーバーヘッドも小さくありません。

3. ガベージコレクター

3.1 新世代

1.シリアル

アルゴリズム: マークコピーアルゴリズム

説明: シンプルで効率的なシングルコア マシン。クライアント モードのデフォルトの新世代コレクター。

2.パラレルパーニュー

アルゴリズム: マークコピーアルゴリズム

注: GC スレッド並列バージョンは、単一 CPU のシナリオではあまり効果的ではありません。クライアントモードのJVMでよく使用される

3. パラレルスカベンジ

アルゴリズム: マークコピーアルゴリズム

注: 目標は、制御可能なスループット (スループット = ユーザー コードの実行時間 / (ユーザー コードの実行時間 + ガベージ コレクション時間)) を達成することです。

3.2 旧世代

1.シリアルオールド

アルゴリズム: マーク圧縮アルゴリズム

説明: 平均的なパフォーマンス、シングルスレッド バージョン。 1.5 より前では Parallel Scavenge で使用されていました。 CMS のフォールバックとして。

2.パラレルオールド

アルゴリズム: マーク圧縮アルゴリズム

説明: GC マルチスレッド並列。一緒に使用される従来のシリアル スカベンジとパラレル スカベンジを置き換えます。

3.CMS

アルゴリズム: マークスイープアルゴリズム

説明: CPU リソースに敏感で、一時停止時間が長くなります。マーク アンド スイープ アルゴリズムはメモリの断片化を生成し、パラメータによって断片のマージとデフラグを有効にすることができます。基本的にG1に置き換えられました

3.3 G1

アルゴリズム: マーク圧縮アルゴリズム

説明: マルチコアおよび大容量メモリのマシン、GC マルチスレッド並列実行、低停止、高回復効率に適しています。

V. 結論

JVM には、この記事では触れられていない、安全ノード、安全領域、カード テーブル、書き込みバリアなど、HotSpot 実装アルゴリズムの詳細を含む、自動メモリ管理に関する多くの知識があります。それぞれの内容は、詳しく研究する価値があります。

面接のために質問をただ暗記するのでなければ、練習を通して学習内容を検証するのが最善の方法です。そうでなければ、この種の知識は 3 分未満の映画のようなもので、その内容を記憶することは困難です。

コンテンツ全体も傅兄弟の学習と整理のプロセスであり、今後もさらに深く掘り下げて共有していく予定です。興味のある友達は一緒に議論したり学んだりすることができます。

<<:  クロスリージョンシナリオで分散システムの一貫性を解決するにはどうすればよいでしょうか?

>>:  モノリシックアーキテクチャから分散データ永続化へ、ORMフレームワークMybatis

推薦する

海外でも使いやすい格安クラウドホストをおすすめします

安価なクラウド ホストは数多くあり、特に海外のホストでは価格が驚くほど安い場合があります。しかし、信...

CDNコンテンツ配信ネットワークがサイト最適化に与える影響についての簡単な説明

インターネットの発展は**スタイルであり、技術は常に革新されています。ウェブサーバーの発達に伴い、多...

#高性能 VPS# racknerd: 年間 69 ドル、KVM、2.5G (DDR4)/2 コア (Ryzen 9 3900X)/40gNVMe/6T トラフィック

8月末、racknerdはLinux+AMD+NVMe SSDシリーズの高性能VPSにさらに2つのプ...

誰もが開発者になれる: SAP が一般開発者とプロの開発者向けにツール、組み込み AI、無料の学習体験を提供

SAP は、一般開発者とプロの開発者がデジタル変革を加速できるように支援する新しい製品とサービスを発...

クラウドコンピューティングの今後はどうなるのでしょうか?分散クラウド

パブリック クラウドにより、IT チームがデータを操作し、クラウド ネイティブな方法で新しいアプリケ...

コンテンツマーケティング記事を書くためのヒント

一定のライティングスキルを持つことは、インターネット マーケターの基本的なスキルであると言えるでしょ...

クラウド コンピューティングは誇大宣伝を生き延びたのでしょうか?

2010 年と 2011 年には、クラウド コンピューティングの明るい未来についての予測がニュースの...

ウェブマスターがプロモーション前に決定する必要がある3つの主要な要素の詳細な説明

ウェブサイトのトラフィックを増やしたい場合、当然ながらプロモーションは欠かせません。しかし、ウェブマ...

Buyvm-7USD/KVM/Windows/2GB RAM/40GB SSD/2TB トラフィック

いまだに高額で低構成の VPS を使っているなら、あなたは本当に時代遅れです。 buyvm.net ...

cloud.net - 5ドル/512Mメモリ/標準ONAPPクラウド/世界中に12のデータセンター

cloud.net は、ONAPP クラウド アーキテクチャに基づくまったく新しいクラウド ホスティ...

greencloudvps-$9/KVM/512M メモリ/250G ハードディスク/10G ポート/無制限トラフィック/DDOS 保護

マイニングをする人はたくさんいますし、大容量のハードドライブを備えた VPS を必要とする人もたくさ...

私のSEO運用方法について簡単にお話しします

まず、ユーザー エクスペリエンスが最も重要です。検索エンジンのアルゴリズムがどのように変化しても、こ...

大手ブランドはマーケティングのためにどのように「牛を借りる」のでしょうか?

中国の伝統文化の枠組みの中で、牛は確かに人々にとって身近な、珍しく縁起の良い生き物です。そのイメージ...

Byteshack - $3/Xen/2IP/384m メモリ/7g SSD/500g トラフィック/G ポート

drServer.net の 2 つの XEN ブランドの VPS はそれぞれプロモーション用の大型...

racknerd の 29% オフ VPS の簡単なレビュー。racknerd の仕組みを大まかに説明します (-8K HD、HBO を視聴可能)

racknerdの特別VPSのKVMモデルを29%割引で手に入れました。racknerdがどんなもの...