WeakMap 本身释放,而 keyObject 没有释放的情况下,value 会释放吗?
博客園markdown不太好看,可以轉到git閱讀https://sologgfun.github.io/look/
const keyObject = ['keyObject']; new WeakMap().set(keyObject, ['value']);問題:現在 ['value'] 會被釋放嗎?
聽說WeakMap是o(1)復雜度的,而且不會存在內存泄漏問題,那么就只有一種實現機制,就是value直接通過一個隱形鍵掛在keyObject上。
但如果是這樣,而WeakMap本身又沒有引用它之前添加過那些內容,那么是不是如果keyObject不釋放,即便WeakMap實例釋放了,通過該WeakMap實例添加在keyObject上的value是不是也都不會釋放,從而形成另一種內存泄漏?
jsperf.com只能測試性能,不知道內存泄漏該如何測試?
答案:會正確被釋放
測試過程:
[1]Chrome DevTools 控制臺上有一個小眾的 API 叫
queryObjects(),它可以從原型樹上反查所有直接或間接的繼承了某個對象的其它對象,比如
queryObjects(Array.prototype)可以拿到所有的數組對象,
queryObjects(Object.prototype)則基本上可以拿到頁面里的所有對象了(除了繼承自Object.create(null)的對象之外)。而且關鍵是這個 API 會在內存里搜索對象前先進行一次垃圾回收。
【測試1】
const key = new WeakMap(); const map = new WeakMap(); map.set(key, new WeakMap()); undefined;在chrome控制臺運行
查到了 3 個對象,符合預期
【測試2】
const key = new WeakMap(); new WeakMap().set(key, new WeakMap()); undefined;在chrome控制臺運行
只有一個WeakMap沒有被回收
那么WeakMap是怎么做到的呢?
核心在于WeakMap上的kv對是弱引用的
V8 的實現,是在 GC 上開洞的
https://github.com/v8/v8/blob/4b9b23521e6fd42373ebbcb20ebe03bf445494f9/src/objects/hash-table.h#L336
https://github.com/v8/v8/blob/4b9b23521e6fd42373ebbcb20ebe03bf445494f9/src/heap/scavenger.cc#L465WeakMap
里用的就是這個 EphemeronHashTable,EphemeronHashTable 存儲著的鍵和值都是弱引用
let wm = new WeakMap([[k1, v1], [k2, v2]]) // vm = {k1:v1, k2:v2}wm.size // no such propertywm.keys(); // no such functionwm.forEach(...) // unable to be iteratedWeakMap有2個特點
看一下WeakMap的polyfill
var WeakMap = function() {this.name = '__wm__' + uuid() };WeakMap.prototype = {set: function(key, value) {Object.defineProperty(key, this.name, {value: [key, value],});return this;},get: function(key) {var entry = key[this.name];return entry && (entry[0] === key ? entry[1] : undefined);},... };—— WeakMap的key必須是Object類型的原因
—— WeakMap的key不可枚舉的原因
延伸閱讀
1.Object.defineProperty(obj, "prop", propDesc)和obj.prop = value的區別?
[譯]JavaScript中的屬性:定義和賦值的區別
2.什么是弱引用?
垃圾回收機制不考慮對該對象的引用。
也就是說,如果其他對象都不再引用該對象,那么垃圾回收機制會自動回收該對象所占用的內存,不考慮該對象是否還在該弱引用的結構中。
WeakMap不能遍歷,是因為成員都是弱引用,隨時可能消失,遍歷機制無法保證成員的存在,很可能剛剛遍歷結束,成員就取不到了。
參考資料
轉載于:https://www.cnblogs.com/cndotabestdota/p/11552309.html
與50位技術專家面對面20年技術見證,附贈技術全景圖總結
以上是生活随笔為你收集整理的WeakMap 本身释放,而 keyObject 没有释放的情况下,value 会释放吗?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: filebeat获取nginx的acce
- 下一篇: Go 命令行参数,JSON 序列化与反序