中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

JVM虛擬機四種引用及GC實踐方法是什么

發布時間:2021-12-21 13:46:32 來源:億速云 閱讀:125 作者:iii 欄目:編程語言

本篇內容介紹了“JVM虛擬機四種引用及GC實踐方法是什么”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!

一、背景

Java的內存回收不需要程序員負責,JVM會在必要時啟動Java GC完成垃圾回收。Java以便我們控制對象的生存周期,提供給了我們四種引用方式,引用強度從強到弱分別為:強引用、軟引用、弱引用、虛引用。

二、簡介

1.強引用 StrongReference

StrongReference是Java的默認引用形式,使用時不需要顯示定義。任何通過強引用所使用的對象不管系統資源有多緊張,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.原可用內存和總內存");
        //實例化10M的數組并與strongReference建立強引用
        byte[] strongReference = new byte[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);
        }
}

運行結果:

JVM虛擬機四種引用及GC實踐方法是什么cdn.xitu.io/2018/1/7/160cd0dc536b2384?imageView2/0/w/1280/h/960/format/webp/ignore-error/1">

2.弱引用 WeakReference

如果一個對象只具有弱引用,無論內存充足與否,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.原可用內存和總內存");
        //創建弱引用
        WeakReferenceweakRerference = new WeakReference(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.原可用內存和總內存");
        //建立軟引用
        SoftReferencesoftRerference = new SoftReference(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]被回收
        SoftReferencesoftRerference2 = new SoftReference(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的數組后");
        //建立虛引用
        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.執行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會把虛引用的對象放到引用隊列里面。可用來在對象被回收時做額外的一些資源清理或事物回滾等處理。 由于無法從虛引獲取到引用對象的實例。它的使用情況比較特別,所以這里不把虛引用放入表格進行對比。這里對強引用、弱引用、軟引用進行對比:參考文章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實踐方法是什么”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

石阡县| 绥江县| 平陆县| 兴山县| 夹江县| 威信县| 郑州市| 高邑县| 黄骅市| 皋兰县| 历史| 益阳市| 阿尔山市| 洪雅县| 景泰县| 汤原县| 理塘县| 门头沟区| 富阳市| 内江市| 仁寿县| 昭通市| 黎平县| 道孚县| 鹤山市| 乐平市| 集安市| 鄂托克前旗| 镇赉县| 新疆| 平罗县| 迭部县| 贵州省| 苍南县| 石泉县| 墨脱县| 旌德县| 唐海县| 光山县| 鞍山市| 始兴县|