WeakRef的作用和使用

文章目錄

    • WeakRef的作用和使用
      • 使用 `WeakRef` 避免強引用:原理與實踐
        • 一、`WeakRef` 的核心特性
        • 二、`WeakRef` 與強引用的對比
        • 三、`WeakRef` 的使用場景與示例
          • 1. 非關鍵數據緩存(避免緩存導致內存泄漏)
          • 2. 跟蹤對象生命周期(不干擾回收)
        • 四、`WeakRef` 的使用限制與注意事項
        • 五、最佳實踐:何時使用 `WeakRef`?
        • 總結

WeakRef的作用和使用

使用 WeakRef 避免強引用:原理與實踐

在 JavaScript 中,強引用是導致內存泄漏的常見原因之一:當一個對象被其他對象(或變量)強引用時,即使它已不再被需要,垃圾回收機制(GC)也無法回收它,因為引用關系會被視為“仍在使用”。而 WeakRef(弱引用) 提供了一種“不阻礙垃圾回收”的引用方式,允許開發者在不阻止對象被回收的前提下,臨時訪問對象。

一、WeakRef 的核心特性
  • 弱引用特性WeakRef 對目標對象的引用不會被 GC 視為“有效引用”,即如果對象僅被 WeakRef 引用(無其他強引用),GC 可以正常回收該對象。
  • 臨時訪問能力:通過 WeakRefderef() 方法,可在對象未被回收前獲取其引用;若對象已被回收,deref() 返回 undefined
二、WeakRef 與強引用的對比
引用類型對 GC 的影響適用場景
強引用(如 let a = obj阻止 GC 回收被引用對象,直至引用被解除(如 a = null需長期持有對象的場景(如全局狀態、緩存核心數據)
弱引用(WeakRef不阻止 GC 回收對象,對象可被隨時回收臨時訪問對象,且不希望阻礙其回收的場景(如緩存非核心數據、跟蹤對象生命周期)
三、WeakRef 的使用場景與示例

WeakRef 適用于**“需要引用對象,但不希望該引用影響對象的回收”**的場景,典型如非關鍵緩存、臨時狀態跟蹤等。

1. 非關鍵數據緩存(避免緩存導致內存泄漏)

普通緩存(如 Map)使用強引用存儲鍵值對,若緩存的對象不再被業務邏輯使用,但仍被緩存引用,會導致內存泄漏。而 WeakRef 可用于緩存非核心數據,允許 GC 在內存緊張時自動回收未使用的緩存對象。

示例

// 創建弱引用緩存:存儲對象的弱引用
const weakCache = new Map();// 緩存對象:用 WeakRef 包裝目標對象
function cacheObject(key, obj) {// 用 WeakRef 包裝 obj,避免強引用const weakRef = new WeakRef(obj);weakCache.set(key, weakRef);
}// 獲取緩存:通過 deref() 訪問對象(可能已被回收)
function getCachedObject(key) {const weakRef = weakCache.get(key);if (weakRef) {const obj = weakRef.deref(); // 若對象未被回收,返回 obj;否則返回 undefinedif (obj) {return obj; // 成功獲取緩存} else {weakCache.delete(key); // 對象已回收,清理緩存鍵}}return null; // 緩存不存在或對象已回收
}// 測試:
const data = { id: 1, value: '臨時數據' };
cacheObject('tempData', data);console.log(getCachedObject('tempData')); // { id: 1, value: '臨時數據' }// 解除強引用:此時 data 僅被 WeakRef 引用
data = null;// 手動觸發 GC(實際中由瀏覽器自動觸發,此處僅為演示)
global.gc(); // 需在 Node.js 中啟用 --expose-gc 標志console.log(getCachedObject('tempData')); // null(對象已被回收)
2. 跟蹤對象生命周期(不干擾回收)

當需要監控對象是否被 GC 回收(如日志記錄、資源清理)時,WeakRef 可配合 FinalizationRegistry 使用,在對象被回收后執行回調,且不阻礙回收。

FinalizationRegistry 作用:注冊一個回調函數,當被弱引用的對象被 GC 回收時,自動執行該回調(可用于清理與對象關聯的其他資源)。

示例

// 創建一個注冊表:對象被回收時觸發回調
const registry = new FinalizationRegistry((key) => {console.log(`對象 ${key} 已被垃圾回收`);// 此處可執行清理操作,如刪除關聯的臨時文件、日志記錄等
});// 創建弱引用并注冊回收回調
function trackObject(key, obj) {const weakRef = new WeakRef(obj);// 注冊:當 obj 被回收時,調用 registry 的回調,并傳入 keyregistry.register(obj, key); return weakRef;
}// 測試:
const obj = { name: '測試對象' };
const weakRef = trackObject('obj1', obj);console.log(weakRef.deref()); // { name: '測試對象' }// 解除強引用
obj = null;// 手動觸發 GC
global.gc(); 
// 輸出:"對象 obj1 已被垃圾回收"(回調執行)
四、WeakRef 的使用限制與注意事項

WeakRef 雖然能避免強引用,但并非“萬能解決方案”,使用時需注意以下限制:

  1. 不可靠的訪問性
    由于 WeakRef 引用的對象可能在任何時候被 GC 回收(即使剛調用 deref() 成功獲取),因此不能依賴 WeakRef 存儲關鍵數據(如用戶會話、未保存的表單數據)。適合存儲“丟失后可重新生成”的數據(如臨時計算結果、緩存的非核心配置)。

  2. 性能與 GC 壓力
    頻繁創建 WeakRef 可能增加 GC 的工作負擔,因為 GC 需要額外跟蹤弱引用關系。因此,避免在高頻操作(如循環、事件回調)中濫用 WeakRef

  3. WeakMap/WeakSet 的區別

    • WeakMap/WeakSet 僅能以對象為鍵,且鍵的弱引用特性使其自動管理條目(鍵被回收后,條目自動刪除)。
    • WeakRef 可對任意對象創建弱引用,更靈活,但需手動管理引用的生命周期(如結合 FinalizationRegistry 清理)。
      兩者適用場景互補:WeakMap 適合鍵值對緩存,WeakRef 適合單獨跟蹤對象。
  4. 瀏覽器兼容性
    WeakRef 是 ES2021 新增特性,現代瀏覽器(Chrome 84+、Firefox 79+、Edge 84+)和 Node.js 14.6+ 已支持,但需注意低版本環境的兼容問題(可通過轉譯工具或 polyfill 處理)。

五、最佳實踐:何時使用 WeakRef
  • 非關鍵緩存:存儲可重新生成的數據(如 API 響應緩存、計算結果),允許 GC 在內存不足時回收。
  • 生命周期跟蹤:監控對象是否被回收(如調試日志、資源清理鉤子)。
  • 避免內存泄漏:替代強引用存儲臨時對象(如 DOM 節點的臨時引用、大型數據的臨時訪問)。
總結

WeakRef 通過弱引用特性,解決了“需要引用對象但不希望阻礙其回收”的問題,是避免強引用導致內存泄漏的有效工具。但需注意其“訪問不可靠”的特性,僅用于非關鍵場景,并結合 FinalizationRegistry 管理對象回收后的清理工作。合理使用 WeakRef 可提升應用的內存效率,減少泄漏風險。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/92414.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/92414.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/92414.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【華為機試】332. 重新安排行程

文章目錄332. 重新安排行程題目描述示例 1:示例 2:提示:解題思路核心思路算法流程圖歐拉路徑原理DFS回溯機制字典序優化策略復雜度分析算法實現要點完整題解代碼332. 重新安排行程 題目描述 給你一份航線列表 tickets ,其中 tic…

通信算法之300:CRC表生成方式-CRC8、CRC16、CRC32-輸入字節

"CRC表的MATLAB生成代碼"生成的查找表可以用于快速計算 CRC 值,通過查表法可以顯著提高 CRC 計算效率,尤其適用于需要處理大量數據的場景。下面是一個生成 CRC 查找表(CRC Table)的 MATLAB 代碼,該代碼可以根…

國內使用 npm 時配置鏡像源

在國內使用 npm 時,由于網絡限制可能會遇到下載速度慢或連接超時的問題。通過設置國內鏡像源,可以顯著提升下載速度和穩定性。以下是常用的國內 npm 鏡像源及其配置方法。 查詢當前使用的鏡像源 npm get registry 設置為淘寶鏡像源 npm config set reg…

一篇文章入門TCP與UDP(保姆級別)

🐳第一部分:什么是TCP和UDP? 先給結論:TCP 和 UDP 都是傳輸層協議,負責把數據從一臺電腦 “搬” 到另一臺電腦,但它們的 “搬運風格” 完全不同 📦 比喻:TCP 像 "打電話"&#xff…

2024年測繪程序設計比賽--空間探索性分析(數據為2025年第三次模擬數據)

想要在2026年參加這個比賽的&#xff0c;可以加入小編和其它大佬所建的群242845175一起來備賽&#xff0c;為2026年的比賽打基礎&#xff0c;也可以私信小編&#xff0c;為你答疑解惑一、讀寫文件 internal class Read {public static List<Point> pts new List<Poin…

力扣 hot100 Day68

84. 柱狀圖中最大的矩形 給定 n 個非負整數&#xff0c;用來表示柱狀圖中各個柱子的高度。每個柱子彼此相鄰&#xff0c;且寬度為 1 。 求在該柱狀圖中&#xff0c;能夠勾勒出來的矩形的最大面積。 class Solution { public:int largestRectangleArea(vector<int>&…

生成式AI時代,Data+AI下一代數智平臺建設指南

DataAI下一代數智平臺建設指南一、生成式AI時代的五大數據挑戰二、驅動DataAI平臺建設的核心要素主動選擇&#xff1a;構建競爭壁壘被動應對&#xff1a;解決現有痛點三、DataAI平臺的六大關鍵能力四、騰訊云DataAI產品方案與實踐1. 數據與AI協同層2. 開發與治理層3. 存儲與計算…

FPGA學習筆記——SPI通訊協議簡介

目錄 一、SPI通訊協議簡介 二、SPI物理層 三、SPI協議層 1.通訊模式 &#xff08;一&#xff09;模式零 &#xff08;二&#xff09;模式一 &#xff08;三&#xff09;模式二 &#xff08;四&#xff09;模式三 2.通訊流程 一、SPI通訊協議簡介 SPI&#xff08;Seria…

JavaScript核心概念解析:從基礎語法到對象應用

導語&#xff1a;本文系統梳理JavaScript的核心知識框架&#xff0c;適用于編程入門學習者。內容涵蓋基礎語法、數據類型、函數應用及內置對象&#xff0c;幫助讀者構建清晰的JS知識體系。一、語言基礎與執行原理瀏覽器執行機制渲染引擎&#xff1a;解析HTML/CSS&#xff08;如…

在 Kotlin 中使用函數類型和 lambda 表達式

參考官方文檔: https://developer.android.google.cn/codelabs/basic-android-kotlin-compose-function-types-and-lambda?hl=zh-cn#0 1、 將函數存儲在變量中 作為一種一級結構,函數也屬于數據類型,因此,可以將函數存儲在變量中、將函數傳遞到函數,以及從函數返回函數…

計算機硬件組成原理

&#x1f9e0; 一、計算機的硬件組成&#xff1a;五大核心部件 根據“馮諾依曼體系結構”&#xff0c;現代計算機主要由這 5大部分組成&#xff1a;部件作用通俗解釋1?? 運算器&#xff08;ALU&#xff09;負責算術和邏輯運算會加減乘除和做判斷的“計算工廠”2?? 控制器&a…

告別 window.open,擁抱全新浮窗體驗!

深入了解 Document Picture-in-Picture API&#xff0c;并對比 Modal 的最佳使用場景在前端開發中&#xff0c;我們經常會遇到這樣的需求&#xff1a;彈出一個浮動窗口來顯示一些實時信息、工具欄或視頻內容。過去我們會用 window.open()&#xff0c;后來越來越多的開發者傾向于…

Python爬蟲實戰:研究weiboSpider技術,構建新浪微博數據采集系統

1. 引言 1.1 研究背景 在信息時代,社交媒體已成為人們獲取信息、表達觀點的重要渠道。微博作為其中的典型代表,擁有龐大的用戶群體和活躍的內容生態。截至 2023 年底,微博月活躍用戶數已超過 5.8 億,日均發博量達數千萬條,數據涵蓋社會熱點、公眾情緒、消費偏好等多維度…

HashMap初始化容量為10,還未添加數據時,它的實際容量是多少?

在Java中&#xff0c;當使用 new HashMap<>(10) 初始化一個容量為10的 HashMap 但尚未添加任何數據時&#xff0c;其實際容量&#xff08;底層數組的長度&#xff09;不是10&#xff0c;而是16。原因如下&#xff1a;關鍵機制解析&#xff1a;容量必須是2的冪HashMap要求…

前端開發:CSS(2)—— 選擇器

前面我們初步學習了CSS&#xff0c;對其有了基本的認識。下面我們來具體學習CSS中的選擇器。 目錄 選擇器的種類 1.基礎選擇器 &#xff08;1&#xff09;標簽選擇器 &#xff08;2&#xff09;類選擇器 &#xff08;3&#xff09;id選擇器 &#xff08;4&#xff09;通…

人工智能2.0時代的人才培養和通識教育

目錄引言&#xff1a;從"機器模仿"到"智能協同"的時代跨越一、人工智能2.0的技術演進&#xff1a;從規則到大模型的三次躍遷1. 人工智能0.0&#xff08;1956-2006&#xff09;&#xff1a;規則驅動的"專家系統時代"2. 人工智能1.0&#xff08;20…

管理索引常用的API

二.管理索引常用的API 1.查看現有索引信息 查看所有索引信息列表&#xff1a;curl -X GET http://elk101.k8s.com:9200/_cat/indices?v查看某個索引的詳細信息:curl -x GET http://elk101.k8s.com:9200/linux-2020-10-2溫馨提示: (1)"?v"表示輸出表頭信息&#xff…

當文檔包含表格時,如何結合大模型和OCR提取數據?

在AI應用極速發展的當下&#xff0c;LLM&#xff08;大語言模型&#xff09;與RAG&#xff08;檢索增強生成&#xff09;系統已成為構建智能問答、知識管理等高階應用的核心引擎。 然而&#xff0c;許多團隊在項目落地時遭遇了現實的挑戰&#xff1a;模型的實際表現——無論是回…

機器學習工程化 3.0:從“實驗科學”到“持續交付”的 7 個關卡

一、背景&#xff1a;為什么 90% 的 ML 項目死在了實驗臺&#xff1f; Gartner 2024 報告顯示&#xff0c;87% 的企業機器學習項目未能走出實驗室。原因并非算法落后&#xff0c;而是缺少“工程化骨骼”&#xff1a;數據漂移無人發現&#xff0c;模型上線一周就失效&#xff1b…

BGP筆記整理

一、BGP 基礎概念1. 產生背景BGP&#xff08;Border Gateway Protocol&#xff09;是自治系統&#xff08;AS&#xff09;間的動態路由協議&#xff0c;屬于外部網關協議&#xff08;EGP&#xff09;&#xff0c;用于在不同 AS 之間傳遞路由信息。2. 自治系統&#xff08;AS&am…