溫馨提示×

溫馨提示×

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

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

java中的引用有哪些

發(fā)布時間:2021-11-30 14:28:31 來源:億速云 閱讀:159 作者:iii 欄目:大數(shù)據(jù)

這篇文章主要講解了“java中的引用有哪些”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“java中的引用有哪些”吧!

一、強(qiáng)引用

概念:當(dāng)對象不可達(dá)時,即可回收。

/**
 * 強(qiáng)引用。當(dāng)強(qiáng)引用指針不存在時,對象將被回收
 * 也可以理解為 ROOT 引用消失時,對象將被回收
 */
public class StrongReference {

    /**
     * jvm在執(zhí)行g(shù)c時 將回調(diào)該方法
     * @throws Throwable
     */
    @Override
    protected void finalize() throws Throwable {
        System.out.println("gc doing now !");
    }

    public static void main(String[] args) {
        StrongReference strongReference = new StrongReference();
        
        // 將引用指針移除
        strongReference = null;
        
        // 手動調(diào)用gc
        System.gc();
    }
}

java中的引用有哪些

二、軟引用

概念: 當(dāng)內(nèi)存空間不足時,將被回收。

/**
 * Xmx2oM  設(shè)置最大堆內(nèi)存為20M
 * 軟引用 會在內(nèi)存空間不夠時,進(jìn)行 gc 操作。 從而 回收 軟引用對象
 */
public class MySoftReference {

    public static void main(String[] args) {
        SoftReference<byte[]> softReference = new SoftReference<byte[]>(new byte[1024*1024*10]);

        System.out.println("第一次gc前 : byte[]:" + softReference.get());
        System.gc();
        System.out.println("第一次執(zhí)行g(shù)c后 : byte[]:" + softReference.get());


        byte[] bytes = new byte[1024*1024*12];
        System.out.println("內(nèi)存不夠后 : byte[]:" + softReference.get());
    }
}

java中的引用有哪些

上述代碼的補(bǔ)充:源碼中,我將虛擬機(jī)參數(shù) -Xmx 設(shè)置為20M。 我先后  new 出來的  兩個byte 數(shù)組均超過10M。 目標(biāo)對象均會存放在老年代中。(按照 新生代 : 老年代 = 1:2.) 大概內(nèi)存分布為。 老年代 20 * 2/3 約為13.3M。 年輕代  約為 20 * 1/3 約為 6.7M。其中 年輕代 eden:s0:s1 = 8:1:1 故 Eden 約為 5.3 M 。So/S1 約為0.67M。  如下圖所示,基本跟計(jì)算出來的結(jié)果吻合。至于  多出來的部分,個人理解,jvm對計(jì)算出的堆大小自我調(diào)優(yōu)勒。

java中的引用有哪些

基于對堆內(nèi)存的分析??梢钥闯?。 第一次  老年代  裝入  10 M的 對象。  第二次  想要  裝入 12M 對象??隙ㄑb不下。 由于是 軟引用。 jvm gc 時會將這部分內(nèi)容先回收掉。 所以這里沒有 出現(xiàn)OOM 的問題。

三、弱引用 (比較重要,面試??碱}之一)

備注: ThreadLocal 里使用勒 弱引用。會產(chǎn)生內(nèi)存泄露的問題。詳見 ( https://my.oschina.net/u/4141142/blog/4523523 )

概念:jvm無視該引用。該對象可被弱引用對象獲取到對象的實(shí)例。 當(dāng)jvm執(zhí)行g(shù)c時,將直接被回收。(提前條件:沒有強(qiáng)引用存在)。

示例一:

/**
 * 弱引用 虛擬機(jī)無視該引用。只要gc 一定會被回收(前提該對象沒有被強(qiáng)引用)
 */
public class Test {

    public static void main(String[] args) {

        Teacher teacher = new Teacher();
        WeakReference<Teacher> weakReference = new WeakReference<Teacher>(teacher);
        System.out.println(weakReference.get());
        // 若不將 teacher 置為null,則還存在一個強(qiáng)引用。不會被gc回收
        //teacher = null;
        System.gc();
        System.out.println(weakReference.get());
    }

java中的引用有哪些

示例二:

/** * User 對象持有 Teacher 對象的強(qiáng)引用。 * 當(dāng)teacher 被置為null 時。 teacher 的強(qiáng)應(yīng)用 隨之消失。 * 而 User 對 Teacher 的強(qiáng)引用還在。 故 user.getTeacher() 并不是null * 所以 teacher 并不會被 gc  回收。 * * 當(dāng) user 也被置為null時。 user 對 teacher 的強(qiáng)引用也不存在勒。 * 此時 teacher  將會被gc回收 */public class Test1 {public static void main(String[] args) {
        User user = new User();        Teacher teacher = new Teacher();        teacher.setName("zs");        user.setTeacher(teacher);        WeakReference<Teacher> weakReference = new WeakReference<Teacher>(teacher);        System.out.println(System.identityHashCode(weakReference.get()));        System.out.println(System.identityHashCode(teacher));        System.out.println(System.identityHashCode(user.getTeacher()));        teacher = null;        System.out.println(user.getTeacher().getName());        // 當(dāng)user 置為null 時, 對teacher 的強(qiáng)引用消失。 此時 teacher 將會被回收。        user = null;        System.gc();        System.out.println(weakReference.get());    }
}

java中的引用有哪些

示例三:

public class People extends WeakReference<Teacher> {

    public People(Teacher referent) {
        super(referent);

    }
}

/**
 * People 繼承自WeakReference<T>  People也是一個虛擬引用對象。
 * 所以teacher 被置為null時,強(qiáng)引用指針被清除。
 * teacher 就會被gc回收。
 */
public class Test2 {

    public static void main(String[] args) {

        Teacher teacher = new Teacher();
        People people = new People(teacher);

        teacher = null;

        System.gc();
        System.out.println(people.get());
    }
}

java中的引用有哪些

四、虛引用

概念:該引用很雞肋。一個對象被虛引用所引用時。并不能獲取到該實(shí)例的對象。只有當(dāng)該對象被回收時,才會收到通過并存入隊(duì)列中。基本上用于操作直接內(nèi)存來使用的。 可用于對一些重要對象的gc的監(jiān)聽?;蛘弑O(jiān)聽gc的頻率(不如打印gc日志來的簡單直觀)。

以下 jvm參數(shù)  -Xmx20M。 當(dāng)然也可以更小,主要是為了看gc 的效果。

/**
 * 虛擬引用
 * 比較雞肋,虛擬引用的對象,并不能get()出來。 而是直接操作 操作系統(tǒng)內(nèi)存的。
 * 虛擬引用的目標(biāo)對象,被回收后,會存入隊(duì)列中
 * 需要新啟一個線程監(jiān)聽該隊(duì)列中,是否有數(shù)據(jù)。有數(shù)據(jù) 則 回收掉直接內(nèi)存。
 */
public class MyPhantomReference {

    private static  final List<Object> LIST = new LinkedList<Object>();
    private static  final ReferenceQueue<MyPhantomReference> QUEUE = new ReferenceQueue<MyPhantomReference>();

    public static void main(String[] args) {
        PhantomReference<MyPhantomReference>  phantomReference = new PhantomReference<MyPhantomReference>(new MyPhantomReference(),QUEUE);

        new Thread( () -> {
            while(true){
                LIST.add(new byte[1024*1024]);
                try{
                    Thread.sleep(1000);
                }catch(Exception e){
                    e.printStackTrace();
                    Thread.currentThread().interrupt();
                }
                System.out.println(phantomReference.get());
            }
        }).start();


        new Thread( () -> {
            while(true){
                Reference<? extends MyPhantomReference> poll = QUEUE.poll();
                if(poll != null){
                  System.out.println("虛擬引用被jvm回收啦 ----" + poll);
                }
            }
        }).start();


        try{
           Thread.sleep(500);
        }catch(Exception e){
            e.printStackTrace();
        }
    }
}

java中的引用有哪些

感謝各位的閱讀,以上就是“java中的引用有哪些”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對java中的引用有哪些這一問題有了更深刻的體會,具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是億速云,小編將為大家推送更多相關(guān)知識點(diǎn)的文章,歡迎關(guān)注!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI