本篇內(nèi)容介紹了“JVM虛擬機四種引用及GC實踐方法是什么”的有關(guān)知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!
創(chuàng)新互聯(lián)公司是一家集網(wǎng)站建設(shè),興隆企業(yè)網(wǎng)站建設(shè),興隆品牌網(wǎng)站建設(shè),網(wǎng)站定制,興隆網(wǎng)站建設(shè)報價,網(wǎng)絡(luò)營銷,網(wǎng)絡(luò)優(yōu)化,興隆網(wǎng)站推廣為一體的創(chuàng)新建站企業(yè),幫助傳統(tǒng)企業(yè)提升企業(yè)形象加強企業(yè)競爭力??沙浞譂M足這一群體相比中小企業(yè)更為豐富、高端、多元的互聯(lián)網(wǎng)需求。同時我們時刻保持專業(yè)、時尚、前沿,時刻以成就客戶成長自我,堅持不斷學(xué)習(xí)、思考、沉淀、凈化自己,讓我們?yōu)楦嗟钠髽I(yè)打造出實用型網(wǎng)站。
Java的內(nèi)存回收不需要程序員負(fù)責(zé),JVM會在必要時啟動Java GC完成垃圾回收。Java以便我們控制對象的生存周期,提供給了我們四種引用方式,引用強度從強到弱分別為:強引用、軟引用、弱引用、虛引用。
StrongReference是Java的默認(rèn)引用形式,使用時不需要顯示定義。任何通過強引用所使用的對象不管系統(tǒng)資源有多緊張,Java GC都不會主動回收具有強引用的對象。
public class StrongReferenceTest { 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){ StrongReferenceTest.printlnMemory("1.原可用內(nèi)存和總內(nèi)存"); //實例化10M的數(shù)組并與strongReference建立強引用 byte[] strongReference = new byte[10*StrongReferenceTest.M]; StrongReferenceTest.printlnMemory("2.實例化10M的數(shù)組,并建立強引用"); 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); } }
運行結(jié)果:
cdn.xitu.io/2018/1/7/160cd0dc536b2384?imageView2/0/w/1280/h/960/format/webp/ignore-error/1">
如果一個對象只具有弱引用,無論內(nèi)存充足與否,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.原可用內(nèi)存和總內(nèi)存"); //創(chuàng)建弱引用 WeakReferenceweakRerference = new WeakReference(new byte[10*WeakReferenceTest.M]); WeakReferenceTest.printlnMemory("2.實例化10M的數(shù)組,并建立弱引用"); System.out.println("weakRerference.get() : "+weakRerference.get()); System.gc(); StrongReferenceTest.printlnMemory("3.GC后"); System.out.println("weakRerference.get() : "+weakRerference.get()); } }運行結(jié)果:3.軟引用 SoftReference軟引用和弱引用的特性基本一致, 主要的區(qū)別在于軟引用在內(nèi)存不足時才會被回收。如果一個對象只具有軟引用,Java GC在內(nèi)存充足的時候不會回收它,內(nèi)存不足時才會被回收。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.原可用內(nèi)存和總內(nèi)存"); //建立軟引用 SoftReferencesoftRerference = new SoftReference(new byte[10*SoftReferenceTest.M]); SoftReferenceTest.printlnMemory("2.實例化10M的數(shù)組,并建立軟引用"); System.out.println("softRerference.get() : "+softRerference.get()); System.gc(); SoftReferenceTest.printlnMemory("3.內(nèi)存可用容量充足,GC后"); System.out.println("softRerference.get() : "+softRerference.get()); //實例化一個4M的數(shù)組,使內(nèi)存不夠用,并建立軟引用 //free=10M=4M+10M-4M,證明內(nèi)存可用量不足時,GC后byte[10*m]被回收 SoftReferencesoftRerference2 = new SoftReference(new byte[4*SoftReferenceTest.M]); SoftReferenceTest.printlnMemory("4.實例化一個4M的數(shù)組后"); System.out.println("softRerference.get() : "+softRerference.get()); System.out.println("softRerference2.get() : "+softRerference2.get()); } }運行結(jié)果:4.虛引用 PhantomReference從PhantomReference類的源代碼可以知道,它的get()方法無論何時返回的都只會是null。所以單獨使用虛引用時,沒有什么意義,需要和引用隊列ReferenceQueue類聯(lián)合使用。當(dāng)執(zhí)行Java GC時如果一個對象只有虛引用,就會把這個對象加入到與之關(guān)聯(lián)的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.原可用內(nèi)存和總內(nèi)存"); byte[] object = new byte[10*PhantomReferenceTest.M]; PhantomReferenceTest.printlnMemory("2.實例化10M的數(shù)組后"); //建立虛引用 ReferenceQueuereferenceQueue = new ReferenceQueue(); PhantomReferencephantomReference = new PhantomReference(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.執(zhí)行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()); } }運行結(jié)果:三、小結(jié)強引用是 Java 的默認(rèn)引用形式,使用時不需要顯示定義,是我們平時最常使用到的引用方式。不管系統(tǒng)資源有多緊張,Java GC都不會主動回收具有強引用的對象。 弱引用和軟引用一般在引用對象為非必需對象的時候使用。它們的區(qū)別是被弱引用關(guān)聯(lián)的對象在垃圾回收時總是會被回收,被軟引用關(guān)聯(lián)的對象只有在內(nèi)存不足時才會被回收。 虛引用的get()方法獲取的永遠(yuǎn)是null,無法獲取對象實例。Java GC會把虛引用的對象放到引用隊列里面。可用來在對象被回收時做額外的一些資源清理或事物回滾等處理。 由于無法從虛引獲取到引用對象的實例。它的使用情況比較特別,所以這里不把虛引用放入表格進(jìn)行對比。這里對強引用、弱引用、軟引用進(jìn)行對比:參考文章https://segmentfault.com/a/1190000009707894https://www.cnblogs.com/hysum/p/7100874.htmlhttp://c.biancheng.net/view/939.htmlhttps://www.runoob.com/https://blog.csdn.net/android_hl/article/details/53228348
“JVM虛擬機四種引用及GC實踐方法是什么”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識可以關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實用文章!