JVM仮想マシン13の深さの理解は:参照とGCの練習の4種類についての話します

Javaで4つの参照タイプ

川や湖] [Javaの技術のJava、テクニカルエンジニアアリステーションのマイクロチャネル公共番号。ジャワにコミット学習経験を、共有するためにSSM、SpringBoot、MySQLの、分散、ミドルウェア、クラスタ、Linuxでは、ネットワーク、マルチスレッド、時折話すポイントドッカー、ELKだけでなく、ドライ商品や技術著者:黄斜めには、Javaの関連技術に焦点を当てフルスタックの開発!(国民の関心の後には、返信の「Java」Javaは、基本的な高度、およびプロジェクトの建築家や他の無料の学習教材、より多くのデータベース、分散、サービス及びその他の人気のマイクロ学習ビデオ技術、豊富なコンテンツ、理論と実践の両方を受け取ることはできませんまた、研究ガイドのジャワ、Javaプログラマのインタビューガイドおよびその他の呉服資源の原作者となります提示)

 

9eedaaa588bef997bef63a7160fa349134bdb78c

一、背景

Javaのガベージコレクションは、プログラマが責任を負う必要はありませんが、JVMは必要なときにガベージコレクションを完了するために、JavaのGCを起動します。私たちは強いから弱いの強さを理由に、基準の4種類の私たちに利用可能なオブジェクトのライフサイクルを制御することができるように、Javaは、次のとおりです。強い参照、ソフト参照、弱参照、ファントム参照。 

第二に、はじめに

1.強い参照StrongReference

StrongReference Javaは、明示的に定義された使用せずに、デフォルトの紹介フォームです。強い参照することにより、任意のオブジェクトがどんなに神経システムリソースを使用し、JavaのGCは強い参照を持つオブジェクトを再利用するためのイニシアチブを取ることはありません。

{クラスStrongReferenceTest公共

	のpublic static int型M = 1024 * 1024; 

	公共の静的な無効printlnMemory(タグ文字列){ 
		ランタイムランタイム= Runtime.getRuntime(); 
		int型= M StrongReferenceTest.M; 
		System.out.printlnは( "\ N-"タグ+ + ":"); 
		のSystem.out.println(Runtime.freeMemory()/ M + "M(フリー)/" + Runtime.totalMemory()/ M + "M(トータル)"); 
	} 
	
	公共の静的な無効メイン(文字列[]引数){ 
		StrongReferenceTest.printlnMemory( "原稿1つの利用可能なメモリと総メモリ。。"); 
		
		//アレイ10Mは、インスタンス化strongReference強い参照が確立されている
		[] = strongReference新しい新しいバイトをバイト[10 * StrongReferenceTest.M]; 
		StrongReferenceTest.printlnMemory ( "2. 10Mアレイをインスタンス化し、強い基準を確立する"); 
		のSystem.out.println( "strongReference:" + strongReference)。
		
		System.gc();
		StrongReferenceTest.printlnMemory( "3.GC后"); 
		System.out.println( "strongReference:" + strongReference)。

		// strongReference = NULL;后、强引用断开了
		strongReference = NULL; 
		StrongReferenceTest.printlnMemory( "4强引用断开后。"); 
		System.out.println( "strongReference:" + strongReference)。
		
		System.gc(); 
		StrongReferenceTest.printlnMemory( "5.GC后"); 
		System.out.println( "strongReference:" + strongReference)。
		} 
}

結果:


 

2.弱参照弱い参照

オブジェクトは、オブジェクトが自動的に回収される場合のみ弱参照後にのみ弱参照、か否かを十分なメモリ、JavaのGCを持っている場合。

public class WeakReferenceTest {
	
	public static int M = 1024*1024;
	
	public static void printlnMemory(String tag){
		Runtime runtime = Runtime.getRuntime();
		int M = WeakReferenceTest.M;
		System.out.println("\n"+tag+":");
		System.out.println(runtime.freeMemory()/M+"M(free)/" + runtime.totalMemory()/M+"M(total)");
	}
	
	public static void main(String[] args){  
		WeakReferenceTest.printlnMemory("1.原可用内存和总内存");

		//创建弱引用
		WeakReference<Object> weakRerference = new WeakReference<Object>(new byte[10*WeakReferenceTest.M]);   
		WeakReferenceTest.printlnMemory("2.实例化10M的数组,并建立弱引用");
		System.out.println("weakRerference.get() : "+weakRerference.get());
		
		System.gc();
		StrongReferenceTest.printlnMemory("3.GC后");
		System.out.println("weakRerference.get() : "+weakRerference.get());
	}   
}

运行结果:

 


 

3.软引用 SoftReference

软引用和弱引用的特性基本一致, 主要的区别在于软引用在内存不足时才会被回收。如果一个对象只具有软引用,Java GC在内存充足的时候不会回收它,内存不足时才会被回收。

public class SoftReferenceTest {
	
	public static int M = 1024*1024;
	
	public static void printlnMemory(String tag){
		Runtime runtime = Runtime.getRuntime();
		int M = StrongReferenceTest.M;
		System.out.println("\n"+tag+":");
		System.out.println(runtime.freeMemory()/M+"M(free)/" + runtime.totalMemory()/M+"M(total)");
	}
	
	public static void main(String[] args){
		SoftReferenceTest.printlnMemory("1.原可用内存和总内存");
		
		//建立软引用
		SoftReference<Object> softRerference = new SoftReference<Object>(new byte[10*SoftReferenceTest.M]);
		SoftReferenceTest.printlnMemory("2.实例化10M的数组,并建立软引用");
		System.out.println("softRerference.get() : "+softRerference.get());
	  
		System.gc();  
		SoftReferenceTest.printlnMemory("3.内存可用容量充足,GC后");
		System.out.println("softRerference.get() : "+softRerference.get());  

		//实例化一个4M的数组,使内存不够用,并建立软引用
		//free=10M=4M+10M-4M,证明内存可用量不足时,GC后byte[10*m]被回收
		SoftReference<Object> softRerference2 = new SoftReference<Object>(new byte[4*SoftReferenceTest.M]);
		SoftReferenceTest.printlnMemory("4.实例化一个4M的数组后");
		System.out.println("softRerference.get() : "+softRerference.get());
		System.out.println("softRerference2.get() : "+softRerference2.get());  
	 } 
}

运行结果:

 


 

4.虚引用 PhantomReference

从PhantomReference类的源代码可以知道,它的get()方法无论何时返回的都只会是null。所以单独使用虚引用时,没有什么意义,需要和引用队列ReferenceQueue类联合使用。当执行Java GC时如果一个对象只有虚引用,就会把这个对象加入到与之关联的ReferenceQueue中。

public class PhantomReferenceTest {

	public static int M = 1024*1024;

	public static void printlnMemory(String tag){
		Runtime runtime = Runtime.getRuntime();
		int M = PhantomReferenceTest.M;
		System.out.println("\n"+tag+":");
		System.out.println(runtime.freeMemory()/M+"M(free)/" + runtime.totalMemory()/M+"M(total)");
	}
	
	public static void main(String[] args) throws InterruptedException {
		
		PhantomReferenceTest.printlnMemory("1.原可用内存和总内存");
		byte[] object = new byte[10*PhantomReferenceTest.M];		
		PhantomReferenceTest.printlnMemory("2.实例化10M的数组后");
		
	    //建立虚引用
	    ReferenceQueue<Object> referenceQueue = new ReferenceQueue<Object>();
	    PhantomReference<Object> phantomReference = new PhantomReference<Object>(object,referenceQueue);  
	    
	    PhantomReferenceTest.printlnMemory("3.建立虚引用后");
	    System.out.println("phantomReference : "+phantomReference); 
	    System.out.println("phantomReference.get() : "+phantomReference.get());
	    System.out.println("referenceQueue.poll() : "+referenceQueue.poll());
	    
	    //断开byte[10*PhantomReferenceTest.M]的强引用
	    object = null;  
	    PhantomReferenceTest.printlnMemory("4.执行object = null;强引用断开后");
	    
	    System.gc();
	    PhantomReferenceTest.printlnMemory("5.GC后");
	    System.out.println("phantomReference : "+phantomReference); 
	    System.out.println("phantomReference.get() : "+phantomReference.get());
	    System.out.println("referenceQueue.poll() : "+referenceQueue.poll());	    
	   
	    //断开虚引用
	    phantomReference = null;
		System.gc(); 
		PhantomReferenceTest.printlnMemory("6.断开虚引用后GC");
	    System.out.println("phantomReference : "+phantomReference);
	    System.out.println("referenceQueue.poll() : "+referenceQueue.poll());	    	
	}
}

运行结果:

 


 

三、小结

Javaはデフォルトの紹介フォームへの強い参照である、我々は通常の参照に最も頻繁に使用する、定義の使用を表示する必要はありません。どんなにタイトなシステムリソース、JavaのGCは強い参照を持つオブジェクトを再利用するためのイニシアチブをとるません。弱参照と非オブジェクト参照オブジェクトを使用する場合に一般に必要ソフト参照。両者の違いは、弱参照オブジェクトが常に関連付けられているオブジェクトがソフト参照のみがメモリ不足で回収されます関連しているとき、ガベージコレクション、リサイクルされます。取得するための仮想参照のget()メソッドは、オブジェクトのインスタンスを取得することができない、常にnullです。JavaのGCは、仮想物体の内部キューに参照によって参照されます。オブジェクトが回復したときには、このようなクリーンアップや物事のロールバックプロセスなど、いくつかの追加のリソースを行うために使用することができます。リードので参照のインスタンスに仮想物体から得ることができません。その使用量は、それは比較のために、このテーブルへの仮想的な基準ではない、むしろ特殊です。ここで強い参照、弱参照に、ソフト参照を比較しました。

参照型 GCは、十分なJVMのメモリであり、 GC時にJVMのメモリ不足
強い参照 回復していません 回復していません
弱参照 それは回収され、 それは回収され、
ソフト参照

マイクロチャネル公共番号[黄色]小さなランププログラマのメーカー、インターネット業界の新しい知識、生涯学習の実践者。懸念は「、 "のiOS"、 "PubMedの"、 "AI"、 "アンドロイド"、 "フロントエンド"、 "ジャワ"、 "パイソン"、 "C ++"、 "ビッグデータ"、 "機械学習"、 "アルゴリズム" 返信した後BAT「」学校のトリック「」書かれた「」インタビュー「」表面が対応する無料の学習教材を介して取得することができます「」コンピュータの基本「」LeetCode「およびその他のキーワード。

 

 

おすすめ

転載: www.cnblogs.com/xll1025/p/11369910.html