Javascript 中弱引用的查找表

2024-01-03

我有一个树结构,其中动态添加和删除元素。这些元素是从网络动态加载的。我想要实现的是拥有一个查找表,将元素的 id 映射到树中的实际元素。现在,使用简单的映射或对象时的问题是它持有对树元素的强引用,这会在一段时间后使内存膨胀。由于节点 >= 14.6.0 且 Chrome >= 84据说支持 WeakRef https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakRef我想我可以制作一个将 WeakRefs 保存到我的树元素的 Map,然后简单地deref()并查看元素是否仍然存在。我尝试对此进行测试,但似乎不起作用。我的最小测试如下所示:

const lookup = new Map();
let element = new Object({id:"someid", data: {}});

lookup.set(element.id, new WeakRef(element));
console.dir(lookup.get("someid").deref());
// as expected output is { id: 'someid', data: {} }

element = null;
console.log(element);
// as expected output is null

// simply calling global.gc() didn't work
// so i made this loop which allocates mem *and* calls global.gc() to
// force garbage collection
// problem: infinite loop because deref always returns the dereferenced
// value which should have gone since element was set to null

while (lookup.get("someid").deref()) {
  const a = new Array(1000);
  // enabled with --expose-gc in node
  global.gc();
}

console.dir(lookup.get("someid").deref());

正如上面评论中所写,问题是循环永远不会结束 因为 deref 调用总是返回一个值,尽管元素 var 被设置为空。

我在这里错过了什么吗?如果没有,这就是它应该如何工作的, 我怎样才能实现拥有弱引用映射的目标(WeakMap 不是 这里有一个选项,因为通过 id 查找元素的成本是 O(n)?。


我在这里错过了什么吗?

是的:您缺少注释中的注释文档 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakRef例如,您已链接到:

如果您的代码刚刚为目标对象创建了 WeakRef,或者从 WeakRef 的 deref 方法获取了目标对象,则该目标对象将不会被回收,直到当前 JavaScript 作业结束(包括在该作业运行的任何 Promise 反应作业)。脚本作业结束)。也就是说,您只能“看到”在事件循环的轮次之间回收对象。

而且当然:

尽可能避免
正确使用 Wea​​kRef 需要仔细考虑,并且最好尽可能避免。避免依赖规范未保证的任何特定行为也很重要。何时、如何以及是否发生垃圾收集取决于任何给定 JavaScript 引擎的实现。

也就是说,实现你的目标是完全有可能的;您的测试用例太简单(根据上面引用的注释),无法显示它。这是一个固定版本:

const lookup = new Map();

(function () {
  let element = { id: "someid", data: {} };
  lookup.set(element.id, new WeakRef(element));
  element = null;

  console.log(lookup.get("someid").deref());

  setTimeout(() => {
    global.gc();
    console.log(lookup.get("someid").deref());
  }, 0);
})();
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Javascript 中弱引用的查找表 的相关文章

  • GraphQL 预期可迭代,但未找到字段 xxx.yyy 的迭代

    我目前正在尝试使用 NodeJS 进行 GraphQL 但我不知道为什么以下查询会出现此错误 library name user name email 我不确定是否type of my resolveLibrary是对的 因为在任何例子中我
  • 了解 sort() 比较函数

    我正在使用一个电子商务平台 该平台无法重新排序产品属性字段的选项 这真的很糟糕 因为要插入新选项 您几乎必须删除所有现有选项并重新开始 我正在尝试在客户端进行操作 这是我正在处理的内容 这是针对鞋码的 9 EE 9 1 2 EE 10 EE
  • 启用/禁用由用户输入确定的复选框

    我有一个简单的表单 用户可以在其中输入他的联系号码 如果联系号码以 07 开头 则该复选框已启用 其他我需要禁用它的复选框 我已经编写了一些代码 但我面临的问题是 当用户键入 01 时 它会被禁用 但如果他们继续在 01 之后添加任何其他数
  • 如何动态突出显示网页上的字符串?

    我想创建带有 url 的页面 例如 http xyzcorp schedules 2015Aug24 Aug28 Jim Hawkins http xyzcorp schedules 2015Aug24 Aug28 Billy Bones
  • 确定元素是在页面折叠上方还是下方

    我有一些页面有多个输入框 用户可以在其中输入文本 在单击 下一步 按钮之前 需要填写其中一些内容 我弹出验证错误供用户查看 但是如果问题不在页面上 我希望页面滚动到它 而不是他们必须搜索丢失 错误的字段 我有一个滚动到位 但我无法确定要滚动
  • 使用文件 API 将资源加载到 Three.js 中

    我想创建导入 3D 模型以在浏览器中查看的功能 方法是使用File API http www html5rocks com en tutorials file dndfiles Three js 加载器在我托管的文件上运行良好 我的理解是加
  • Nodejs - 检查隐藏文件

    我正在迭代文件目录 想知道是否可以测试文件是否隐藏 目前 我只是检查文件是否以 开头或不 这适用于 Mac 也许还有 Linux 但是 我想知道如何在 Windows 上做到这一点 另外 句点会在所有版本的 Linux 中隐藏该文件吗 Th
  • 有没有办法将变量从 javascript 导入到 sass 或反之亦然?

    我正在制作一个依赖于块概念的 CSS 网格系统 所以我有一个基本文件 例如 max columns 4 block width 220px block height 150px block margin 10px 它被 mixin 使用 m
  • 判断一个数字是否能被 3 或 5 整除 (FizzBu​​zz)

    如何根据输出是否能被 3 或 5 整除来更改输出 如果它能被 3 整除 我想显示 rock 如果它能被 5 整除 我想显示 star 类似于 FizzBu zz 如果两者都有 他们都会看到 这是我的代码 if var n Math floo
  • 循环遍历元素并逐步为每个元素应用 CSS 规则

    我有一个网格布局 每个网格布局中都有不同数量的元素 我想动态添加内联grid column通过循环遍历 div 中存在的每个元素的 CSS 规则 ul 与一类 list 所以 HTML 代码的输出需要是 ul class list ul u
  • Docker - SequelizeConnectionRefusedError:连接 ECONNREFUSED 127.0.0.1:3306

    我正在尝试使用 Docker 容器启动并运行我的 Nodejs 应用程序 我不知道可能出了什么问题 当我使用控制台调试凭据时 凭据似乎已正确传递 另外启动sequel pro并使用相同的用户名和密码直接连接似乎也可行 当节点在容器中启动时
  • 在 jQuery 可排序中对多个选定项目进行排序?

    我试图在 jQuery 可排序集中选择多个项目 然后将选定的项目一起移动 这是我的弱点开始尝试使其发挥作用 http jsfiddle net benstenson CgD8Y 这是代码 HTML div class container d
  • jQM / jquery-collagePlus 使用问题

    我正在使用 jQM 构建应用程序 并且尝试使用 jquery collagePlus http ed lea github io jquery collagePlus http ed lea github io jquery collage
  • 如何调用 google 的 getBasicProfile() 来仅单击按钮即可登录 google?

    我在我的网站上使用谷歌登录
  • Google 地图 API:忽略 DirectionService 请求中的季节性限制

    我目前正在开发一张地图 其中显示两点之间的最短路线 使用不同的交通工具 我注意到 有时 例如在冬季关闭的道路不会被考虑在内 我发现我可以使用方向服务 下面的代码 忽略高速公路 收费站和渡轮 但我一生都无法弄清楚如何 是否可以忽略季节性限制
  • 使用日期字符串数组在引导日期选择器中设置禁用月份不起作用

    我有一个日期选择器 其配置如下 HTML div class input group date div
  • 计算文本选择的 xy 位置

    我正在尝试使用 DOM 元素创建自己的文本选择 是的 我的意思是当您在此元素中选择文本时 您会在文本后面看到蓝色背景 这个想法是停止默认行为 蓝色 并使用我自己的元素来完成工作 方法是找到选择的 xy 位置 然后放置绝对定位的元素 我希望能
  • 禁用特定 div 上的 Tab 键

    我有以下结构 div div Some content div div Some content div div 我想 禁用 div2 上的 tab 键 我的意思是按下 tab 键时 div2 的元素不会获得焦点 有没有简单的方法可以使用
  • Phantom-node模块无法加载外部资源

    我正在开发一个nodejs服务器 它将发布的html呈现为pdf png或jpg https github com svenhornberg pagetox https github com svenhornberg pagetox ser
  • Flowtype 属性“msg”缺失为 null 或未定义

    我发现 Flow 很难用 我明白那个Array find可以返回或未定义 因此 通过阅读以下内容 github Array find on Array 引发 https github com facebook flow issues 351

随机推荐

  • Delphi死锁解释/解决方案

    在服务器应用程序上 我们有以下内容 一个称为 JobManager 的单例类 另一个类是 Scheduler 它不断检查是否需要向 JobManager 添加任何类型的作业 当需要这样做时 调度程序会执行以下操作 TJobManager S
  • 让 Kubernetes 等待 Pod 终止,然后再从服务端点中删除

    根据Pod 的终止 https kubernetes io docs concepts workloads pods pod lifecycle pod termination 步骤 7 与 3 同时发生 有什么办法可以防止这种情况发生并且
  • R 中插入符中的并行处理

    插入符号文档中给出了允许并行处理以下代码的工作原理 library doMC registerDoMC cores 5 All subsequent models are then run in parallel 但在最新的 R 版本 3
  • jQuery 更改类名

    我想根据 td 标签的 id 更改 td 标签的类 td class change me 我希望能够在其他 dom 对象的单击事件中执行此操作 如何获取 td 的 id 并更改其类别 Using jQuery你可以set类 无论它是什么 w
  • 如何在 Spring Boot 中使用 @Lazy 延迟加载 RabbitMQ 队列?

    实际上 在我的 RabbitMQ 配置中 我为每个队列声明了 10 个消费者 因此 所有消费者线程都是在我的 Spring Boot 应用程序完全启动之前创建的 因此应用程序启动需要时间 我想在项目启动时延迟加载所有 Rabbitmq 队列
  • Python:使用泰勒级数逼近 ln(x)

    我正在尝试建立 ln 1 9 的近似值 精度在十位数字之内 即 641853861 我正在使用一个从 ln 1 x 1 x 构建的简单函数 到目前为止 这是我的代码 function for ln 1 x 1 x def taylor tw
  • 带鼠标滚轮的 D3 v4 平移

    如何使用 d3 js 版本 4 通过鼠标滚轮进行平移 我发现这个例子使用的是 v3 但它不适用于 v4 示例链接 http bl ocks org ahmohamed 82ac20ccc949470e3206
  • 如何禁用 Sun jvm 的内联优化?

    我需要做一些实验来展示内联对我的代码的影响 有人知道如何禁用 sun jvm 内联吗 我搜索了http www oracle com technetwork java javase tech vmoptions jsp 140102 htm
  • getRunningAppProcesses() 返回被销毁的进程

    我正在使用以下代码片段来检查我是否使用了应用程序finish ed 确实不再运行 ActivityManager am ActivityManager this getSystemService ACTIVITY SERVICE List
  • 即使库已链接,对符号的未定义引用

    当链接我正在处理的项目时 链接器给出以下错误 usr bin ld Includes and Libs lib libsfml21rca a SoundFile o undefined reference to symbol sf read
  • javafx 和可序列化

    在旧的 AWT 库中 Point类和Color类是可序列化的 JavaFX 中都没有 我想保存一个数组列表Drawable到一个文件 这是界面 import javafx scene canvas GraphicsContext publi
  • mouseover() mouseout() jQuery add/removeClass 问题

    我正在尝试使用 mouseover mouseout addClass 和 removeClass 的组合来创建一个简单的鼠标悬停效果 基本上 当用户将鼠标悬停在某个元素上时 我想应用不同的边框 1px 灰色虚线 初始状态为 1px 纯白色
  • Groovy 可以动态添加或重写 POJO 上的方法吗?

    如果我有 java class MyClass public String getName return hector 和这个类的一个实例 Groovy 可以重写实例上的 getName 方法吗 当然你可以使用动态元类 http groov
  • 创建一个包含开始日期和结束日期之间的日期的列表

    使用 SQL Server 2016 我有一个具有不同开始日期和结束日期的表 Start End 2018 01 01 00 00 2018 01 01 23 59 2018 01 12 05 33 2018 01 13 13 31 201
  • 如何在玩笑中模拟/监视 useState 挂钩?

    我试图监视 useState React hook 但我总是测试失败 这是我的 React 组件 const Counter gt const counter setCounter useState 0 const handleClick
  • 如何从本地maven存储库中删除通过install:install-file添加的jar文件?

    mvn install install file Dfile phonegap 1 1 0 jar DgroupId phonegap DartifactId phonegap Dversion 1 1 0 Dpackaging jar 我
  • System.ArgumentException 路径中存在非法字符

    我在用Path Combine 并且其中一个字符串包含 Unicode 字符 我明白了 System ArgumentException exception illegal characters in path 根据MSDN http ms
  • 转换 UTF8 文本以在 URL 中使用

    我正在开发一个国际网站 它使用 UTF8 显示非英语字符 我还使用包含项目名称的友好 URL 显然我不能在 URL 中使用非英文字符 这种转换有某种常见的做法吗 我不确定应该用哪些英文字符替换它们 有些字符非常明显 例如 到 e 但其他字符
  • Gradle 7.2:如何应用自定义 Gradle SETTINGS 插件?

    我正在将 buildSrc 约定插件迁移到独立插件中 有很多为 Project 对象创建 Gradle 插件的示例 但真正缺乏 Settings 和 Gradle 我想集中我们在 gradle settings kts 文件中使用的存储库列
  • Javascript 中弱引用的查找表

    我有一个树结构 其中动态添加和删除元素 这些元素是从网络动态加载的 我想要实现的是拥有一个查找表 将元素的 id 映射到树中的实际元素 现在 使用简单的映射或对象时的问题是它持有对树元素的强引用 这会在一段时间后使内存膨胀 由于节点 gt