前の記事では、自動メモリ管理がオブジェクトへのメモリの割り当てと、オブジェクトに割り当てられたメモリのリサイクルという 2 つの部分に分かれていると述べました。この記事では後者、つまりオブジェクトに割り当てられたメモリのリサイクルについて説明します。メモリをリサイクルするには、英語名が GC (Garbage Collection) であるガベージ コレクション メカニズムを使用する必要があります。
このパートでは、次の質問を解決する必要があります:
1. どのメモリをリサイクルする必要がありますか?
2.いつリサイクルされますか?
3.リサイクル方法は?
どのメモリをリサイクルする必要がありますか?
ヒープおよびメソッド領域内のメモリはリサイクルする必要がありますが、残りはリサイクルする必要はありません。
スレッドが共有するのはヒープとメソッド領域だけなので、残りはスレッドとともに生きて死んでいきますが、スレッドが終了するとメモリは自然に再利用されるので、気にする必要はありません。
いつリサイクルされますか?
(1) ヒープ内:
オブジェクトが「消滅」すると、そのメモリをリサイクルする必要があります。物体が死んだということは何を意味するのでしょうか?参考にするところがないので、無駄です。それで、それが死んでいるかどうかをどうやって見分けるのでしょうか?
参照カウント アルゴリズムオブジェクトに参照カウンタを追加します。オブジェクトへの参照があるたびに、カウンタの値は 1 です。参照が失敗すると、カウンタの値は -1 になります。カウンタの値が 0 の場合、オブジェクトは参照されなくなった、つまり「死ぬ可能性がある」ことを意味します。
しかし、循環参照の問題という欠点があります。下の図のように、ヒープ内の 2 つのオブジェクトが役に立たない場合でも、相互に参照しており、カウンター値が 1 以上であるため、再利用することはできません。
到達可能性分析生成されたすべてのオブジェクトは、「GC ルート」と呼ばれるルートのサブツリーです。 GC ルートから開始して下方向に検索する、検索によって移動されるパスは参照チェーンと呼ばれます。オブジェクトに GC ルートに到達するための参照チェーンがない場合、そのオブジェクトは到達不能であると言われます。つまり、オブジェクトは GC によってリサイクルできます。これは Java でよく使用されるメソッドです。
下の図のヒープ内の参照されていないオブジェクトと同様に、それらはリサイクルできます。
オブジェクトにまだ参照があるかどうかを確認するにはどうすればよいでしょうか? Java には 4 つのタイプの参照があります:
強参照: Object o=new Object(). 強参照が存在する限り、GC は参照されたオブジェクトを再利用しません。
ソフトリファレンス: 便利ではあるが必須ではないいくつかのオブジェクトについて説明します。システムがメモリをオーバーフローしそうになると、メモリがリサイクルされます。
弱い参照: GC が実行される限り、それはリサイクルされます。
仮想参照: これは最も弱い参照関係であり、仮想参照を通じてオブジェクト インスタンスを取得することはできません。その機能は、このオブジェクトがコレクターによってリサイクルされたときにシステム通知を受け取ることです。
(2) メソッド領域:
メソッド領域に格納されている内容は、仮想マシン クラス情報、定数、静的変数、ジャストインタイム コンパイラによってコンパイルされたコード、およびその他のデータ。そのため、メソッド領域でガベージ コレクションを実行し、放棄された定数と役に立たないクラスをリサイクルします。
定数が廃止されたかどうかを判断するにはどうすればよいですか?
参照カウントを見てください。オブジェクトが定数を参照していない場合、それは定数が破棄され、再利用できることを意味します。
クラスが役に立たないかどうかを判断するにはどうすればよいでしょうか?
3 つの状況があります:
a. このクラスのすべてのインスタンスがリサイクルされています。
b. このクラスをロードした ClassLoader はリサイクルされました。
c. このクラスに対応する java.lang.Class オブジェクトはどこからも参照されず、このクラスのメソッドにはどこからもリフレクションを通じてアクセスできません。
リサイクル方法? 理論としては 4 つのアルゴリズムがあります。
• マークスイープ アルゴリズム• コピー アルゴリズム
• マーク照合アルゴリズム
• 世代別コレクション アルゴリズム
実装としての 5 種類のコレクター:
#追記
メモリ オーバーフロー: システムが割り当てられませんもう必要なスペースを取り出してください。たとえば、ヒープ内の新しいオブジェクトにこれ以上メモリを割り当てることはできず、スタックがいっぱいの場合は、新しいスタック フレームをスタックにプッシュできません。
メモリ リーク: メモリがオブジェクトによって占有され、返されない場合、それはメモリ リークと呼ばれます。
上記は、JVM のガベージ コレクション メカニズムの詳細な説明です。その他の関連する質問については、PHP 中国語 Web サイトを参照してください:以上がJAVA仮想マシン(JVM)の詳しい紹介(3) - ガベージコレクションの仕組みの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。