【问题标题】:JS Garbage collection: Reference to object properties cause whole object to remain on Memory?JS垃圾收集:对对象属性的引用导致整个对象保留在内存中?
【发布时间】:2023-03-03 05:59:21
【问题描述】:

这个答案似乎是相关的,但我需要更具体的信息:Garbage collection: object properties

假设我有一个全局对象:

var myObj  {
  'some prop' : null
};

和一个返回结果的 Ajax 调用(为了耐心而简化):

result = {
  prop1 : someObj,
  prop2 : otherObj
}

考虑这个操作:

ajax.get('some url', function(result){
  myObj['some prop'] = results.prop2
});

由于对象是通过引用分配的,而不是像原语那样复制,我担心整个 results 对象将保留在内存中,因为我的全局对象 myObj 现在引用了它的一个属性 (prop2) .

我想如果我运行太多 Ajax 请求,这可能会成为数据泄漏的来源。

我不需要所有结果,只需要一些属性。我应该有额外的工作从结果中删除不需要的属性或克隆结果属性而不是分配吗?

我想知道浏览器垃圾收集器是否足够聪明来处理这个问题,和/或这不是一个真正的问题。

【问题讨论】:

  • 我认为不会存储整个result。嵌套对象是参考映射。因此,如果您分配一些内部对象,则不应保留整个地图。但这只是一个猜测,我不确定

标签: javascript ajax object memory-leaks garbage-collection


【解决方案1】:

因为函数参数代表它的局部变量,在执行超出你的 Ajax 函数的作用域后,result 对象将实际上变得无用并且可以被释放。

但也有一些例外,比如循环引用:

function f() {
  var o = {};
  var o2 = {};
  o.a = o2; // o references o2
  o2.a = o; // o2 references o

  return 'azerty';
}

由于Mark-and-sweep algorithm,上述代码会将oo2 释放到垃圾收集,除非您在函数的外部范围中声明其中一个并且可以从全局作用域,因此垃圾收集器可以访问它(因此被视为需要的对象,因此不会从内存中删除)。

SOURCE

【讨论】:

  • results 可以删除,但如果你这样做,myObj['some prop'] = results.prop2 之后将是myObj['some prop'] = null,因为它是一个引用。相反,results.prop2 仍然可以从myObj['some prop'] 访问这一事实让我认为results.prop1 也在记忆中挥之不去。 这是的大问题。如果results.prop1 是一个大对象而我忽略了它,那么在多次调用后我可能会遇到问题。所以我要么做delete results.prop1 要么做myObj['some prop'] = _.clone(results.prop2); delete results; 我想
  • 是的,我同意。本来打算删这个帖子的。只是要注意 - 你最好做_.cloneDeep,因为.clone 突出创建值的浅克隆,所以AFAIK它与通常的参考没有太大区别(但我必须更多地研究这种差异)跨度>
  • 不要删除,因为它会向主题添加信息。 ?
猜你喜欢
  • 2014-03-18
  • 2012-01-03
  • 2013-05-11
  • 1970-01-01
  • 2010-11-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多