ホームページ  >  記事  >  Java  >  Javaのシングルトンモードガベージコレクションの例を詳しく解説

Javaのシングルトンモードガベージコレクションの例を詳しく解説

黄舟
黄舟オリジナル
2017-08-08 10:25:341548ブラウズ

この記事は主にシングルトンモードガベージコレクションの関連情報を詳しく紹介します。興味のある友人はそれを参照してください

ディスカッション提案: シングルトンオブジェクトが長期間使用されない場合、それはどうなりますか? JVM のガベージ コレクション メカニズムによってリサイクルされます。产 まず、なぜこのような疑問が生じたのかについて話しましょう。私は昨年、秦暁波著『Zen of Design Model』という本を読むまで、ゴミのリサイクルがシングルモデルに与える影響について考えたことがありませんでした。この本の中で、j2ee アプリケーションでは、jvm ガベージ コレクション メカニズムが、長期間使用されなかったシングルトン オブジェクトをガベージとして扱い、CPU がアイドル状態のときにリサイクルすることが述べられています。
「Java とパターン」を含む、私が以前に読んだいくつかの設計パターンの本では、jvm ガベージ コレクション メカニズムがシングルトンに与える影響については言及されていませんでした。また、作業プロセス中に、シングルトン オブジェクトがリサイクルされるという経験は一度もありませんでした。また、職場の多くの先輩から、静的プロパティはロード後に解放されないため、あまり多くの静的プロパティを宣言しないように注意されました。したがって、jvm ガベージ コレクションがシングルトン オブジェクトをリサイクルするという記述には懐疑的です。インターネット上の同僚や技術スタッフの間で、この問題に関しては基本的に 2 つの対立する派閥があることが徐々にわかりました。それでは、jvm は長期間使用されていないシングルトン オブジェクトをリサイクルするのでしょうか?

この問題に関して、著者の個人的な意見は次のとおりです: リサイクルされません

以下は私のテストコードです​​

class Singleton {
 private byte[] a = new byte[6*1024*1024];
 private static Singleton singleton = new Singleton();
 private Singleton(){}
 
 public static Singleton getInstance(){
 return singleton;
 }
}

class Obj {
 private byte[] a = new byte[3*1024*1024];
}

public class Client{
 public static void main(String[] args) throws Exception{
 Singleton.getInstance();
 while(true){
  new Obj();
 }
 }
}

このプログラムの目的は、最初に、このシングルトン クラスが 6M のメモリを占有し、その後、プログラムが無限に入ります。ループし、オブジェクトを作成し、jvm にガベージ コレクションを強制的に実行させ、ガベージ コレクション後にメモリがまだ 6M を超えている場合は、シングルトン オブジェクトがガベージ コレクションによってリサイクルされないことを意味します。

このプログラムを実行するために使用される仮想マシンは、私たちが最も使用する Java によって公式に提供される仮想マシンです。バージョンは、jdk1.6.0_12 です。ランタイム VM の引数パラメータは -verbose :gc -Xms20M -Xmx20M です。これは、JVM がガベージ コレクションを実行するたびにメモリ情報が表示され、JVM のメモリが固定の 20M に設定されることを意味します。

実行結果:


……
[Full GC 18566K->6278K(20352K), 0.0101066 secs]
[GC 18567K->18566K(20352K), 0.0001978 secs]
[Full GC 18566K->6278K(20352K), 0.0088229 secs]
……



実行結果から、収集されていないスペースが常に6Mあることがわかります。したがって、作成者は、少なくともホットスポット仮想マシンでは、ガベージ コレクションによってシングルトン オブジェクトがリサイクルされないと考えています。

その後、いくつかの関連情報を確認しました。ホットスポット仮想マシンのガベージ コレクション アルゴリズムはルート検索アルゴリズムを使用しています。このアルゴリズムの基本的な考え方は、「ライブ」オブジェクトについては、最終的にはスタックまたは静的ストレージ領域に残っているその参照まで遡らなければならないということです。ルート (GC ルート) という名前の一連の参照を開始点として使用し、これらのルートから開始して一連のパスを検索し、Java ヒープ内のオブジェクトに到達できる場合、そのオブジェクトは「ライブ」であり、リサイクルできません。 。ルートとして使用できるオブジェクトには次のものがあります。


 仮想マシン スタック (スタック フレーム内のローカル変数テーブル) で参照されるオブジェクト。


メソッド領域のクラスの静的プロパティによって参照されるオブジェクト。
  • メソッド領域の定数によって参照されるオブジェクト。
  •  ローカル メソッド スタック内の JNI によって参照されるオブジェクト。
  • メソッド領域は、クラス関連の情報を格納するために使用される、JVM のメモリ領域です。明らかに、Java のシングルトン モードで作成されたオブジェクトは、2 番目の記事に準拠した独自のクラスの静的プロパティによって参照されるため、シングルトン オブジェクトは JVM によってガベージ コレクションされません。

  • jvmヒープ内のシングルトンオブジェクトはガベージコレクションされませんが、シングルトンクラス自体は長期間使用されなかった場合ガベージコレクションされるのでしょうか? jvm にはメソッド領域のガベージ コレクション メカニズムもあるためです。シングルトン クラスが収集されると、ヒープ内のオブジェクトはルートへのパスを失い、必然的にガベージ コレクションが実行されます。これに関連して、筆者はホットスポット仮想マシンのメソッド領域のガベージ コレクション メソッドを確認しました。jvm アンロード クラスの判定条件は次のとおりです。


このクラスのすべてのインスタンスがリサイクルされている、つまり、このクラスはリサイクルされている。 Java ヒープに存在しないインスタンス。


このクラスをロードした ClassLoader はリサイクルされました。
  • このクラスに対応する java.lang.Class オブジェクトはどこからも参照されておらず、このクラスのメソッドにはどこからもリフレクションを通じてアクセスできません。

3 つの条件がすべて満たされた場合にのみ、JVM はガベージ コレクション中にクラスをアンロードします。明らかに、シングルトン クラスは条件 1 を満たさないため、シングルトン クラスはアンロードされません。つまり、シングルトン クラスの静的参照が JVM ヒープ内のシングルトン オブジェクトを指している限り、ルート検索アルゴリズムに従って、オブジェクトがガベージになるかどうかにかかわらず、シングルトン クラスとシングルトン オブジェクトはガベージ コレクションされません。収集されたかどうか 使用期間は重要ではなく、オブジェクトが「生きている」かどうかによって決まります。オブジェクトが長期間使用されておらず、リサイクルされている場合、コレクション アルゴリズムは、最近使用されていない最も長いアルゴリズムである必要があります。仮想マシンのガベージコレクションに使用されているのは、あまりにも危険ではないでしょうか?以上が筆者の見解です。

以上がJavaのシングルトンモードガベージコレクションの例を詳しく解説の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。