【问题标题】:How to detect if an object has been garbage collected in Javascript?如何检测对象是否已在 Javascript 中被垃圾收集?
【发布时间】:2015-02-17 15:12:50
【问题描述】:

我正在构建一个使用 var 创建“关卡”对象的 javascript 游戏:

function start() {
   var myGameLevel = new Level(2);
}

这个“Level()”对象有很多功能,主要是向 DOM 添加元素并使其具有交互性。简化:

function Level(i) {
    var _difficulty = i;

    this.init = function(){
         jQuery("#container").append(...game elements here...);
         jQuery("#button").on('click', function() {...});
    }
}

我的问题:我如何知道在“start”函数中创建的 Level 对象是否已被垃圾回收?我的目标是只使用“var”变量,这样就没有外部引用。当 DOM 中的所有游戏元素都被清除后,我希望“关卡”对象会从内存中释放出来,但我怎么能确定呢?

【问题讨论】:

  • 如果您使用的是 Chrome,您是否尝试过在调试器中进行内存分析?
  • 好吧,我不知道要找什么?由于整个 Level 对象是匿名的? Chrome 调试器有很多屏幕、列表和选项。我在哪里可以找到我的“关卡”对象?
  • @Kokodoko 你有什么解决方法吗?
  • 我并没有真正研究它,但您可以在 chrome 调试器中发现内存泄漏:如果您不断生成不被垃圾收集的对象,RAM 内存使用量将不断上升。

标签: javascript garbage-collection


【解决方案1】:

弱引用are considered a security risk,因此对浏览器中的非特权代码不可用。

这些问题不适用于特权代码或服务器端 javascript 执行,例如通过 node.js,因此他们可以使用特定于平台的弱参考实现。
例如firefox插件可以使用Components.utils.getWeakReference()

对于某些编程模式WeakMap/WeakSet 可能就足够了,但它们不允许程序观察垃圾收集,因为这样做需要一个键来探测这些数据结构,但持有该键会从一开始就阻止对象被收集。

JS 实现者提出的另一个担忧是,取决于假设的弱引用 API 的强大程度——例如。提供终结通知 - 它可能会暴露大量 GC 行为,这反过来可能会限制未来的实现,因为更改行为可能会破坏 Web 应用程序。


更新:现在有 is a proposal 来标准化 JS 中的弱引用,通过将弱可访问对象的释放与 JS 事件循环联系起来来降低感知风险,从而使行为更具确定性。

更新 2:该提案已在各种浏览器中实现为WeakRef

【讨论】:

  • 所以你是说我实际上不应该使用 "var myLevel = Level()" ?这可能是个好建议,但问题仍然存在:在我将 myLevel 设置为 null 之后,我如何确定 Thing() 没有仍在运行代码?我发现很难在 Chrome Inspector 中确定。
  • 不,我是说检测某些东西已被垃圾收集的唯一方法是弱引用。但是弱引用不适用于非特权代码。
  • 你到底在说什么?该链接中没有任何地方提到安全风险。
  • 你没有注意到保密段吗?机密性是信息安全的一部分。
  • 是的,你有理由,
【解决方案2】:

通常在 javascript 垃圾收集中是不确定的。您无法知道对象是否或何时被垃圾收集。这适用于强引用的对象。

在 ES12 及之后,你可以使用Finalizers

终结器可让您使用 javascript 回调处理对象何时被垃圾回收。仍然存在的限制是,何时执行回调是不确定的。可能需要一分钟或一小时。

// object creation
let abc = new Array(200).fill(true);

const cleanup = new FinalizationRegistry(key => {
  // your code here
});

// tagging variable abc to finalizer
cleanup.register(abc, 'werwer');

// abc = null;

【讨论】:

    【解决方案3】:

    我不认为你可以控制 JavaScript 垃圾收集。 通常,如果没有对变量或对象的引用,则可以收集它。因此,您可以通过设计使对象超出范围的逻辑来增加收集对象的机会。

    【讨论】:

    • 我不用管它,我只想知道对象是否被GC'ed。由于整个事情是匿名的,我无法在控制台或代码中访问它,但它仍然可能存在。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-20
    • 2011-10-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多