最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java資源管理和引用體系的使用詳解

 更新時間:2025年05月13日 11:12:30   作者:找不到、了  
這篇文章主要介紹了Java資源管理和引用體系的使用,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教

Java中的引用類型不僅是內(nèi)存管理的概念,更是資源管理的重要工具。合理使用不同類型的引用可以有效地管理內(nèi)存敏感資源,防止內(nèi)存泄漏和資源浪費。

1、java的引用體系

如下圖所示,可分為四種:強(qiáng)引用、軟引用、弱引用和虛引用。

以下是對四種引用的類比,可以讓大家有個更好的理解。

1、強(qiáng)引用 (Strong Reference)

基本特性

Object obj = new Object(); // 這就是強(qiáng)引用
  • 默認(rèn)引用類型:所有普通對象引用都是強(qiáng)引用。
  • GC行為:只要強(qiáng)引用存在,對象就不會被回收。
  • 內(nèi)存泄漏:無意保留的強(qiáng)引用是內(nèi)存泄漏的主因。

代碼示例:

public class StrongReferenceExample {
    private List<String> cache = new ArrayList<>();
    
    public void addToCache(String data) {
        cache.add(data); // 強(qiáng)引用保留對象
    }
    
    public void clearCache() {
        cache.clear(); // 必須顯式清除
    }
}

2、軟引用 (Soft Reference)

1.基本特性

SoftReference<Object> softRef = new SoftReference<>(new Object());

GC行為

  • 內(nèi)存充足時:保留對象
  • 內(nèi)存不足時:回收對象(在OOM之前)
  • 緩存特性:適合實現(xiàn)內(nèi)存敏感緩存

2.核心特點

  • 動態(tài)調(diào)整緩存大小
  • 當(dāng)系統(tǒng)內(nèi)存充足時,可以緩存更多數(shù)據(jù)以提高性能
  • 當(dāng)內(nèi)存緊張時,自動清理部分緩存,避免內(nèi)存溢出

優(yōu)先級管理

  • 對緩存項設(shè)置優(yōu)先級(如LRU最近最少使用)
  • 內(nèi)存不足時優(yōu)先清理低優(yōu)先級數(shù)據(jù)

3.響應(yīng)內(nèi)存壓力

  • 監(jiān)聽JVM內(nèi)存使用情況(如 Runtime.getRuntime().freeMemory())。
  • 或使用 Java.lang.ref.SoftReference(軟引用)讓GC在內(nèi)存不足時自動回收。
  • 實現(xiàn)方式

實戰(zhàn)示例:基于內(nèi)存壓力softReference的圖片緩存

public class ImageCache {
    private final Map<String, SoftReference<Bitmap>> cache = new HashMap<>();
    
    public Bitmap getImage(String key) {
        SoftReference<Bitmap> ref = cache.get(key);
        return ref != null ? ref.get() : null;
    }
    
    public void putImage(String key, Bitmap image) {
        cache.put(key, new SoftReference<>(image));
    }
}

基于Runtime.freeMemoy()來實現(xiàn)。

import java.lang.ref.SoftReference;
import java.util.HashMap;
import java.util.Map;

public class MemorySensitiveCache<K, V> {
    private final Map<K, SoftReference<V>> cache = new HashMap<>();

    // 存入緩存(使用軟引用,內(nèi)存不足時可被GC回收)
    public void put(K key, V value) {
        cache.put(key, new SoftReference<>(value));
    }

    // 從緩存讀取(可能返回null如果已被GC回收)
    public V get(K key) {
        SoftReference<V> ref = cache.get(key);
        return (ref != null) ? ref.get() : null;
    }

    // 示例:內(nèi)存監(jiān)控線程
    public void startMemoryMonitor() {
        new Thread(() -> {
            while (true) {
                long freeMem = Runtime.getRuntime().freeMemory();
                if (freeMem < 1024 * 1024) { // 如果剩余內(nèi)存 < 1MB
                    System.out.println("內(nèi)存緊張,清理緩存...");
                    cache.clear();
                }
                try { Thread.sleep(1000); } catch (InterruptedException e) {}
            }
        }).start();
    }
}

3、弱引用 (Weak Reference)

3.1、基本特性

  • GC行為下次GC時立即回收(無論內(nèi)存是否充足)
  • 規(guī)范映射:適合存儲元數(shù)據(jù)等輔助信息
WeakReference<Object> weakRef = new WeakReference<>(new Object());

代碼示例:

import java.util.WeakHashMap;

public class WeakHashMapExample {
    public static void main(String[] args) {
        WeakHashMap<Object, String> map = new WeakHashMap<>();
        
        Object key = new Object();
        map.put(key, "Value");
        
        System.out.println("GC 前: " + map.size()); // 1
        
        key = null; // 斷開強(qiáng)引用
        System.gc(); // 觸發(fā) GC
        
        System.out.println("GC 后: " + map.size()); // 0(Entry 被自動清理)
    }
}

4、虛引用 (Phantom Reference)

基本特性

ReferenceQueue<Object> queue = new ReferenceQueue<>();
PhantomReference<Object> phantomRef = new PhantomReference<>(new Object(), queue);

GC行為

  • 對象變得虛引用可達(dá)
  • 引用加入隊列
  • 最終回收內(nèi)存

特殊限制get()方法永遠(yuǎn)返回null

主要用途:精確控制資源清理時機(jī)

5、常見問題

Q1: WeakHashMap的key是弱引用,那value呢?

A: 只有key是弱引用,value是強(qiáng)引用。需要確保value不間接引用key,否則會內(nèi)存泄漏。

Q2: 虛引用get()為什么返回null?

A: 這是設(shè)計使然,虛引用僅用于跟蹤回收事件,不應(yīng)再訪問將死對象。

Q3: 軟引用和弱引用誰更適合緩存?

A: 軟引用適合主緩存(內(nèi)存敏感),弱引用適合輔助緩存(立即釋放)。

四種引用的區(qū)別和聯(lián)系如下圖所示:

2、finalize

finalize:垃圾回收的終結(jié)機(jī)制。

2.1、所屬領(lǐng)域

  • 垃圾回收(Garbage Collection) 的補(bǔ)充機(jī)制。
  • 屬于 java.lang.Object 的基礎(chǔ)方法,與 JVM 的 GC 流程相關(guān)。

2.2、作用

  • 在對象被垃圾回收前,JVM 會調(diào)用 finalize() 方法(如果重寫了該方法),用于執(zhí)行最后的清理操作(如關(guān)閉非內(nèi)存資源)。

2.3、問題

  • 不可靠:JVM 不保證 finalize() 的執(zhí)行時機(jī)(甚至可能不執(zhí)行)。
  • 性能開銷:拖慢 GC 效率(對象需要至少兩次 GC 才能被回收)。
  • 已被廢棄:Java 9 開始標(biāo)記為 @Deprecated,推薦用 java.lang.ref.CleanerAutoCloseable 替代。

2.4、使用場景

想象你租了一間房:

  • 正常情況:退租時主動交還鑰匙(相當(dāng)于 close() 方法)
  • 忘記還鑰匙:房東最后會自己來收鑰匙(相當(dāng)于 finalize()
  • 風(fēng)險:房東可能很久后才來,期間鑰匙被別人撿到可能不安全

代碼示例:

public class Room {
    private static final Set<String> LEAKED_KEYS = new HashSet<>();
    private String roomKey;

    public Room(String key) {
        this.roomKey = key;
        LEAKED_KEYS.add(key); // 登記鑰匙
        System.out.println("拿到鑰匙進(jìn)入房間: " + key);
    }

    // 主動還鑰匙(推薦方式)
    public void returnKey() {
        if (roomKey != null) {
            System.out.println("主動歸還鑰匙: " + roomKey);
            LEAKED_KEYS.remove(roomKey); // 注銷鑰匙
            roomKey = null;
        }
    }

    @Override
    protected void finalize() throws Throwable {
        if (roomKey != null) {
            System.out.println("警告!鑰匙未被歸還: " + roomKey + " (內(nèi)存泄漏)");
            LEAKED_KEYS.remove(roomKey); // 清理登記
        }
    }

    public static void main(String[] args) {
        // 好租客
        Room goodRoom = new Room("A101");
        goodRoom.returnKey();

        // 壞租客
        new Room("B202"); // 直接不保存引用
        
        System.gc();
        try { Thread.sleep(1000); } catch (Exception e) {}
        
        System.out.println("未歸還的鑰匙: " + LEAKED_KEYS);
    }
}

輸出:

拿到鑰匙進(jìn)入房間: A101
主動歸還鑰匙: A101
拿到鑰匙進(jìn)入房間: B202
警告!鑰匙未被歸還: B202 (內(nèi)存泄漏)
未歸還的鑰匙: []

結(jié)論

  • finalize() 只會在 GC 回收對象時執(zhí)行,而 System.gc() 只是建議 GC 運行,不保證立即執(zhí)行。
  • finalize() 不保證一定執(zhí)行,如果程序退出前 GC 沒運行,它就不會被調(diào)用。
  • 不應(yīng)該依賴 finalize() 管理資源(如文件、數(shù)據(jù)庫連接),而應(yīng)該使用 try-with-resources 或手動 close()
  • 同步調(diào)用 finalize() 會阻塞 GC 線程,降低性能。

3、try-with-resources

屬于java的資源管理 → try-with-resources + AutoCloseable。

3.1、所屬領(lǐng)域

  • 資源管理(Resource Management),尤其是需要顯式釋放的資源(如文件、數(shù)據(jù)庫連接、網(wǎng)絡(luò)套接字)。
  • 基于 AutoCloseable 接口(Java 7 引入),屬于語法糖(Syntactic Sugar)。

3.2、作用

  • 自動在 try 代碼塊結(jié)束后調(diào)用資源的 close() 方法,避免資源泄露。
  • 比手動 try-catch-finally 更簡潔安全。

3.3、優(yōu)勢

  • 確定性釋放:資源離開 try 塊立即關(guān)閉。
  • 代碼簡潔:減少嵌套和樣板代碼。
  • 異常友好:支持抑制異常(Suppressed Exceptions)。

代碼示例:

// 實現(xiàn) AutoCloseable,用 try-with-resources 確保資源釋放
class Resource implements AutoCloseable {
    @Override
    public void close() {
        System.out.println("Resource closed!");
    }
}

public class Main {
    public static void main(String[] args) {
        try (Resource r = new Resource()) {
            // 使用資源
        } // 自動調(diào)用 close()
    }
}

finalize和try-with-resources的區(qū)別如下圖所示:

替代 finalize 的方案:

  • CleanerPhantomReference:提供更可控的清理機(jī)制(但復(fù)雜度高)。
  • AutoCloseable + try-with-resources:首選方案。

資源管理的最佳實踐

  • 優(yōu)先實現(xiàn) AutoCloseable 接口,而非依賴 finalize。
  • 對于必須手動管理的資源(如原生內(nèi)存),結(jié)合 ByteBuffer.allocateDirectCleaner 使用。

4、Cleaner

(Java 9+)java.lang.ref.Cleaner。

如下圖所示 :由phant虛引用和隊列來實現(xiàn)。

4.1、Cleaner 的優(yōu)勢

? 確定性更強(qiáng):通過虛引用(PhantomReference)和引用隊列實現(xiàn)

? 更安全:清理操作在獨立線程執(zhí)行,不影響主線程

? 性能更好:不干擾正常垃圾回收流程

? 可控性高:可以顯式注冊/取消清理操作

4.2、底層機(jī)制

  • 引用類型:使用 PhantomReference(虛引用)
  • 引用隊列:被清理對象進(jìn)入引用隊列時觸發(fā)清理
  • 守護(hù)線程:專門的清理線程處理隊列中的對象

代碼示例如下:

// Cleaner 內(nèi)部實現(xiàn)偽代碼
public class Cleaner {
    private final ReferenceQueue<Object> queue = new ReferenceQueue<>();
    private final PhantomReference<Object> phantomRef;
    private final Runnable cleanupAction;
    
    public static Cleaner create() {
        return new Cleaner();
    }
    
    public Cleanable register(Object obj, Runnable action) {
        phantomRef = new PhantomReference<>(obj, queue);
        this.cleanupAction = action;
        startCleanerThread();  // 啟動監(jiān)控線程
        return new CleanableImpl();
    }
    
    private void startCleanerThread() {
        Thread thread = new Thread(() -> {
            while (true) {
                Reference<?> ref = queue.remove(); // 阻塞等待
                if (ref == phantomRef) {
                    cleanupAction.run();
                }
            }
        });
        thread.setDaemon(true);
        thread.start();
    }
}

4.3、執(zhí)行流程

import java.lang.ref.Cleaner;

public class CleanerDemo {
    private static final Cleaner cleaner = Cleaner.create();

    static class Resource implements Runnable {
        @Override
        public void run() {
            System.out.println("Cleaner action executed!");
        }
    }

    public static void main(String[] args) {
        Resource resource = new Resource();
        cleaner.register(new Object(), resource); // 注冊清理動作
        System.gc();
        try { Thread.sleep(1000); } catch (InterruptedException e) {}
    }
}

相比較于finalize和cleaner的區(qū)別:

總結(jié)

通過合理組合這些引用類型,可以構(gòu)建出既高效又安全的資源管理系統(tǒng)。

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • SpringData關(guān)鍵字查詢實現(xiàn)方法詳解

    SpringData關(guān)鍵字查詢實現(xiàn)方法詳解

    這篇文章主要介紹了SpringData關(guān)鍵字查詢實現(xiàn)方法詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-08-08
  • SpringQuartz集群支持JDBC存儲與分布式執(zhí)行的最佳實踐

    SpringQuartz集群支持JDBC存儲與分布式執(zhí)行的最佳實踐

    SpringQuartz集群通過JDBC存儲和分布式執(zhí)行機(jī)制,有效解決了單點故障和擴(kuò)展性問題,本文將詳細(xì)介紹SpringQuartz集群支持的實現(xiàn)原理、配置方法和最佳實踐,助力開發(fā)者構(gòu)建穩(wěn)定可靠的分布式調(diào)度系統(tǒng),感興趣的朋友一起看看吧
    2025-04-04
  • JavaEE Filter敏感詞過濾的方法實例詳解

    JavaEE Filter敏感詞過濾的方法實例詳解

    我們無論是在聊天還是在留言時,都有一些信息不希望別人看到。那么如果過濾這些關(guān)鍵詞呢?下面小編給大家分享JavaEE Filter敏感詞過濾的方法實例詳解,感興趣的朋友一起學(xué)習(xí)吧
    2016-05-05
  • 詳解Spring?Security怎么從數(shù)據(jù)庫加載我們的用戶

    詳解Spring?Security怎么從數(shù)據(jù)庫加載我們的用戶

    這篇文章主要為大家介紹了Spring?Security怎么從數(shù)據(jù)庫加載我們的用戶示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-01-01
  • Java獲取此次請求URL以及服務(wù)器根路徑的方法

    Java獲取此次請求URL以及服務(wù)器根路徑的方法

    這篇文章主要介紹了Java獲取此次請求URL以及服務(wù)器根路徑的方法,需要的朋友可以參考下
    2015-08-08
  • springboot+rabbitmq實現(xiàn)智能家居實例詳解

    springboot+rabbitmq實現(xiàn)智能家居實例詳解

    這篇文章主要為大家介紹了springboot+rabbitmq實現(xiàn)智能家居的示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-07-07
  • java垃圾回收原理之GC算法基礎(chǔ)

    java垃圾回收原理之GC算法基礎(chǔ)

    本章簡要介紹GC的基本原理和相關(guān)技術(shù), 下一章節(jié)再詳細(xì)講解GC算法的具體實現(xiàn)。各種垃圾收集器的實現(xiàn)細(xì)節(jié)雖然并不相同,但總體而言,垃圾收集器都專注于兩件事情:查找所有存活對象,拋棄其他的部分,即死對象,不再使用的對象
    2022-01-01
  • springboot項目main函數(shù)啟動的操作

    springboot項目main函數(shù)啟動的操作

    這篇文章主要介紹了springboot項目main函數(shù)啟動的操作,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-06-06
  • java8、jdk8日期轉(zhuǎn)化成字符串詳解

    java8、jdk8日期轉(zhuǎn)化成字符串詳解

    在本篇文章中小編給大家整理了關(guān)于java8、jdk8日期轉(zhuǎn)化成字符串的相關(guān)知識點和代碼,需要的朋友們學(xué)習(xí)下。
    2019-04-04
  • javaCV視頻處理之提取人像視頻

    javaCV視頻處理之提取人像視頻

    這篇文章主要介紹了利用JavaCV實現(xiàn)提取視頻中的人像并保存為視頻,文中的示例代碼講解詳細(xì),對我們學(xué)習(xí)JavaCV有一定的幫助,需要的可以參考一下
    2021-12-12

最新評論

通辽市| 曲麻莱县| 铜鼓县| 盐源县| 宝丰县| 丹寨县| 枣庄市| 诏安县| 西充县| 双流县| 南澳县| 崇州市| 确山县| 禹州市| 盖州市| 霸州市| 阿城市| 南投市| 武清区| 宜良县| 韶山市| 海原县| 平果县| 汉源县| 神木县| 石林| 仁寿县| 昆明市| 安陆市| 喜德县| 新巴尔虎左旗| 新昌县| 牟定县| 翼城县| 宜良县| 新竹市| 永寿县| 凌云县| 松阳县| 台北县| 新干县|