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

推薦する

外部リンクの削除に別れを告げ、トラブルを解消しましょう。多様なソフト記事リンクはより強力です

ウェブサイトの最適化は外部リンクの宣伝と切り離せません。SEO 最適化では、「外部リンクは王様」とい...

SEOで成功するには?まずは平凡さを捨てることから始めましょう

SEOの人気が高まるにつれて、オンラインマーケティングに従事するほぼすべての企業が優れたSEOを備え...

2021年の分散型クラウドコンピューティング業界の概要

Web3.0 時代は分散型クラウド コンピューティングの発展を促進し、膨大な量のデータが分散型クラウ...

Hostodo の新しい商人、シンプルな VPS レビュー、驚きは少ない

Hostodo は設立されてまだ日が浅いです。そのコンピュータルームは QuadraNet のロサン...

ウェブサイトの統計をバロメーターとして使用して、ウェブサイトの改善の必要性を確認します。

ユーザーのニーズは一定ではないため、Web サイトは常に最新のユーザー ニーズに合わせて調整する必要...

Facebookのグラフ検索の成功または失敗は、ユーザーのプライバシーを保護できるかどうかにかかっている

北京時間1月20日、外国メディアの報道によると、フェイスブックの最大の成功は、常に世界人口の7分の1...

Xenspec: ロサンゼルス データ センターを追加、月額 2.95 ドル、トラフィック無制限、sharktech ライン、簡単なレビュー

これまでHostcatでxenspecを2回紹介してきました。最初はシカゴデータセンターのトラフィッ...

徐志新:企業向けサービスで20年の経験を持つFutong CloudとTeng Cloud Management Servicesは、より説得力があります

[51CTO.comからのオリジナル記事] 伝統的なソリューションディストリビューターからデジタルト...

自給自足のインターネットの例: コンテンツが王様であることが基盤であり、利益の最大化が目標である

安全を保つため、あるいは一時的に妥協するため、選択肢は異なりますが、目的は同じです。すべては発展のた...

Ramnode - 月額3.5ドル 512MBメモリ標準版 openvz 簡易評価

「ramnode-$3.5/512m メモリ/40g SSD/1T トラフィック/シアトル/ニューヨ...

中国の電子商取引茶産業の発展動向分析

今後、電子商取引茶業界はどのような発展傾向を示すのでしょうか?著者がまとめているので見てみましょう。...

クラウドコンピューティングはどのように発展したのでしょうか?どのような技術が関係していますか?

クラウド コンピューティングは、個人や企業のユーザーがオンデマンドで簡単に拡張できる方法でコンピュー...

extravm: 月額 5 ドル、ハイエンド VPS、10Gbps 帯域幅 + ryzen9 3900x + NVMe、1G メモリ/1 コア/15G/5T トラフィック

extravm(~) のハードコア VPS をご紹介します。データ センターは米国マイアミにあり、1...

ユーザー行動研究に基づく不動産ネットワークマーケティングモデル

2010年に始まった不動産規制は、不動産業界全体を最前線に押し上げました。銀行融資は厳しくなり、購入...