【问题标题】:Find orphan scopes to cut memory leaks查找孤立作用域以减少内存泄漏
【发布时间】:2015-04-30 00:42:14
【问题描述】:

我遇到了一些普通侦听器正在关闭范围的情况,例如:

$(window).on('click', function() {
  $scope.doSomething();
})

此侦听器未正确解除绑定,因此此 $scope 从未被垃圾回收。

由于它是一个相当大的 Angular 应用程序,我怀疑这可能发生在许多其他地方。

有没有办法让所有范围都在内存中?从 DOM 元素中获取它们是不够的,因为这正是我想要解决的情况:元素已被销毁,范围的 $$destroyed 属性设置为 true,但它仍在内存中。

如果没有 Angular 方法来获取它,而我只剩下标准的 Javascript 分析,请告诉我,我会删除该问题(因为它可能与标准内存泄漏检测方法重复)。

【问题讨论】:

  • 扮演魔鬼的拥护者 我想说真正的问题不是内存泄漏,而是仍然处于活动状态的事件处理程序。内存泄漏只是一个副作用。我想这一切都归结为你的最后一句话。不过,我不会删除这个问题。

标签: javascript angularjs memory-leaks


【解决方案1】:

有很多方法可以解决这个问题,我个人在我的控制器中有这样的东西

angular.module('something').controller('someCtrl', someFunc);

function someFunc($injectables like $scope){
    var vm = this;
    vm.blah = ...;
    ....

    //at the end
    $scope.$on('$destroy', function(){
       vm = null;
    });

}

仔细查看 angularjs.org 网站上的代码,我在代码中找到了这条评论

当新的作用域没有被隔离或者我们继承自this,并且 父作用域被销毁,属性$$destroyed 被继承 原型。在所有其他情况下,需要设置此属性 当父作用域被销毁时。

据我了解,角度实际上正在破坏您的父范围,您可以看到 $$destroyed 设置为 true。

进一步查看作用域是如何被销毁的。 $destroy 函数前还有一条注释:

从父级删除当前范围(及其所有子级) 范围。删除意味着 调用 {@link ng.$ro​​otScope.Scope#$digest $digest()} 将不再 传播到当前范围及其子范围。删除还意味着当前 范围符合垃圾回收条件。

因此,基于此,我会说,只要您正确销毁您的范围,它就应该不再存在并且不会导致任何内存泄漏。

【讨论】:

  • 感谢您的关注,但这不会阻止$scope 像我给出的示例一样仍在内存中。事实上,我认为$scope 在控制器中时不会消失(控制器本身也不会消失:即使您清除vm,该功能仍然存在)。当它们被完全销毁时,我正在考虑孤立的指令。
  • 好吧,我已经知道角度范围破坏了。我的问题正是如何知道被破坏的范围 没有 被垃圾收集,因为它应该在用户错误的特定情况下我们仍然在某些函数或对象中引用它(比如那个 jQuery 监听器)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-11-29
  • 2012-12-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-18
相关资源
最近更新 更多