JavaScript WeakMap 不断引用经过 gc 处理的对象

2023-11-25

我正在经历 JavaScript 弱映射,在 google chrome 开发者控制台中尝试此代码后,使用 --js-flags="--expose-gc" 运行,我不明白为什么弱映射继续引用 a.b 如果 a 是GC 编辑。

var a = {listener: function(){ console.log('A') }}
a.b = {listener: function(){ console.log('B') }}

var map = new WeakMap()

map.set(a.b, [])
map.set(a, [a.b.listener])

console.log(map) // has both a and a.b

gc()
console.log(map) // still have both a and a.b

a = undefined
gc()
console.log(map) // only have a.b: why does still have a reference to a.b? Should'nt be erased?

更新 2/2020

当我现在运行这段代码时,它按预期工作。我认为在以前版本的 Chrome 中打开控制台会导致对象被保留,但现在不会。重新分配保存对象引用的变量的值将导致该对象被垃圾收集(假设没有其他对象引用它)。


在您的示例代码中,您没有释放您的a多变的。它是一个顶级变量,永远不会超出范围,也永远不会被显式取消引用,因此它保留在 WeakMap 中。一旦代码中不再有对象的引用,WeakMap/WeakSet 就会释放该对象。在你的例子中,如果你console.log(a)在你的一个之后gc()打电话,你仍然会期待a活着,对吗?

下面是一个工作示例,展示了 WeakSet 的实际作用,以及一旦对某个条目的所有引用都消失了,它将如何删除该条目:https://embed.plnkr.co/cDqi5lFDEbvmjl5S19Wr/

const wset = new WeakSet();

// top level static var, should show up in `console.log(wset)` after a run
let arr = [1];
wset.add(arr);

function test() {
  let obj = {a:1}; //stack var, should get GCed
  wset.add(obj);
}

test();

//if we wanted to get rid of `arr` in `wset`, we could explicitly de-reference it
//arr = null;

// when run with devtools console open, `wset` always holds onto `obj`
// when devtools are closed and then opened after, `wset` has the `arr` entry,
// but not the `obj` entry, as expected
console.log(wset);

请注意,打开 Chrome 开发工具会阻止某些对象被垃圾收集,这使得看到这一点比预期更困难:)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

JavaScript WeakMap 不断引用经过 gc 处理的对象 的相关文章

随机推荐

  • 添加超链接到闪亮图

    我制作了一个闪亮的应用程序 使用不同的绘图解决方案来渲染图表ggplot2关于闪亮 我最喜欢的是plotly 我喜欢用户可以与图表交互的事实 plotly用户可以放大图表或单击点 例如散点图 并访问它们的值 我想将散点图上的每个点链接到一个
  • 在 vim 的正则表达式引擎中,为什么有些元字符会被转义,有些则不会?

    为什么必须在正则表达式引擎中转义某些元字符 而不是其他元字符 例如 foo 1 9 按预期工作 但正则表达式 foo 1 9 必须表示为 foo 1 9 在维姆中 有人知道吗 This is because vim actually vi
  • 如何以编程方式保存网页?

    我想以编程方式保存网页 我的意思不仅仅是保存 HTML 我还希望自动存储所有关联的文件 图像 CSS 文件 可能嵌入的 SWF 等 并希望重写本地浏览的链接 预期用途是个人书签应用程序 其中缓存链接内容 以防原始副本被删除 看一眼wget
  • 批量删除除指定文件和目录之外的所有文件和目录[重复]

    这个问题在这里已经有答案了 我正在尝试使用该目录中的 bat 文件删除特定目录中的所有文件和目录 我见过这在 Linux 上完成没有问题 但在 Windows 命令环境中这似乎是一件苦差事 示例 temp 1 bat 保留 temp 特殊文
  • 我应该使用枚举作为鉴别器吗?

    枚举什么时候会崩溃 为了支持现有系统中的新功能 我只是考虑对数据库模式中的实体表实现某种形式的鉴别器 为了从做最少的事情开始 我首先决定在业务实体层使用整数列和 C 枚举 以提高可读性 这将提供穷人的多态性 最终可能发展为实际的多态性 并可
  • 如何将 cv::Mat 转换为 pcl::pointcloud

    如何从 opencv Mat 点云到 pcl pointcloud 颜色对我来说并不重要 重要的是点本身 你可以这样做 pcl PointCloud
  • 比 get_headers() 更快的东西

    我正在尝试制作一个 PHP 脚本来尽快检查网站的 HTTP 状态 我目前正在使用 get headers 并在 mysql 数据库中的 200 个随机 url 循环中运行它 检查全部 200 个 平均需要 2m 48s 我能做些什么来让它
  • Java中的运算符重载

    请问Ja va中是否可以重载运算符 如果它在 Java 中的任何地方使用 请告诉我 不 Java 不支持用户定义的运算符重载 Java 唯一接近 自定义 运算符重载的方面是对字符串的 处理 这会导致常量的编译时连接或使用 StringBui
  • 使用 SPARQL 查询查找最短路径

    我试图了解 SPARQL 查询的计算限制 并且我想知道如何编写一个查询来确定两个对象之间是否存在有向路径 我知道一种针对特定长度的路径执行此操作的方法 SELECT a b c d WHERE a
  • 未捕获的类型错误:当我尝试将数据发送到 url 时,无法读取未定义的属性“ajax”

    我创建了一个表单来获取用户的反馈 我只是尝试将表单数据发送到 url 但我收到此错误 未捕获的类型错误 无法读取未定义的属性 ajax function sendData ajax url www yashkjhsah php type P
  • 打印内核的页表条目

    具有 4 级页表的虚拟内存映射 0000000000000000 00007fffffffffff 47 bits user space different per mm ffff800000000000 ffff80ffffffffff
  • 如果数据库丢失,SQLite 连接失败? (已删除/移动)

    我里面有以下方法class DBConnection 我这样调用该方法 SQLiteConnection conn DBConnection OpenDB 当我想打开连接时 以便我可以执行查询 当我想关闭连接时 我可以调用类似的方法 方法
  • $locationProvider.html5Mode(true) 问题

    一直在处理一些我陷入困境的 locationProvider 问题 我有一个简单的单页页面 但我收到以下错误 TypeError Cannot read property replace of undefined at trimEmptyH
  • Geopy:检索英文国家/地区名称

    我正在尝试反转地理编码坐标并使用 geopy 检索相应的国家 地区代码 然而 Geopy似乎没有提供获取国家代码的方法 因此 我尝试先检索国家 地区名称 然后将它们转换为代码 不幸的是 我的代码给了我非英语的国家 地区名称 如何获取英文国家
  • RxJS Observables 的 Promise.all 行为?

    在 Angular 1 x 中 我有时需要制作多个http请求并对所有响应执行某些操作 我会将所有的承诺放入一个数组中并调用Promise all promises then function results Angular 2 最佳实践似
  • 由于 rJava 导致尝试在 R 中加载包时出现问题

    当我打字时require xlsx 为了加载包xlsx在 R 中 显示以下消息 gt require xlsx Loading required package xlsx Loading required package xlsxjars
  • 将 Python argparse.Namespace() 视为字典的正确方法是什么?

    如果我想使用的结果argparse ArgumentParser 这是一个Namespace对象 具有需要字典或类似映射的对象的方法 请参阅集合 映射 正确的做法是什么 C gt python Python 2 7 3 default Ap
  • Typescript 索引签名和方法

    为什么下面的代码给出ts 2411 error class Greeter key string string number greeting string constructor message string this greeting
  • 如何删除ListBox中的多个选定项?

    我的 Windows 窗体包含两个列表框 Listbox1 包含一些项目 listbox2 为空 当我按下表单上的按钮时 应将 listbox1 中的多个选定项目从 Listbox1 中删除并复制到 Listbox2 中 我尝试在 list
  • JavaScript WeakMap 不断引用经过 gc 处理的对象

    我正在经历 JavaScript 弱映射 在 google chrome 开发者控制台中尝试此代码后 使用 js flags expose gc 运行 我不明白为什么弱映射继续引用 a b 如果 a 是GC 编辑 var a listene