Javascript 角度指令内存泄漏?

Javascript 角度指令内存泄漏?,javascript,angularjs,memory-leaks,Javascript,Angularjs,Memory Leaks,我正在使用这个简单的html文件复制我发现的内存泄漏: <!doctype html> <html> <head> <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.6/angular.min.js"></script> <script> var app = angular.modu

我正在使用这个简单的html文件复制我发现的内存泄漏:

<!doctype html>
<html>
    <head>
        <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.6/angular.min.js"></script>
        <script>
            var app = angular.module('testApp', []);

            app.directive('directive1', function() {
                return {
                    template: '<div directive2></div>',
                    scope: true
                };
            });

            app.directive('directive2', function () {
                function LeakObject() {}

                function Foo() {
                    this.bar = function($scope) {
                            $scope.nottheredude;
                    };
                }

                return {
                    scope: true,
                    link: function($scope) {
                            $scope.memoryThatLeaks = new LeakObject();

                            new Foo().bar({});
                            new Foo().bar($scope);
                    }
                };
            });
        </script>
    </head>
    <body ng-app="testApp">
        <button ng-click="show = !show">Toggle</button>
        <div ng-if="show">The directive <div directive1></div></div>
        <div ng-if="!show">Nothing</div>
    </body>
</html>

var app=angular.module('testApp',[]);
app.directive('directive1',function(){
返回{
模板:“”,
范围:真
};
});
应用指令('directive2',函数(){
函数LeakObject(){}
函数Foo(){
this.bar=函数($scope){
$scope.notthereded;
};
}
返回{
范围:正确,
链接:功能($scope){
$scope.memoryThatLeaks=新泄漏对象();
新的Foo().bar({});
新的Foo().bar($scope);
}
};
});
切换
指令
没有什么
我有一个指令,它只创建一个新的作用域,并且在它的模板中有另一个指令

另一个指令做了一些奇怪的事情(我试图将问题缩小到导致泄漏的原因,这是我发现的复制问题的最短代码)

在我的主html中,我只需使用一个简单的
ng if
在nothing和
directive1
之间切换

请注意,
directive2
还将在名为
LeakObject
$scope
上创建一个新对象。我希望当我切换回nothing div时,这个对象会被垃圾收集,因为指令的作用域应该消失,并且所有的数据都会随之消失,但是根据Chrome的堆快照工具的匿名模式,它不会被未分配

我试图理解为什么会发生这种情况,以及为什么如果我在
bar
方法中注释掉语句,它就不会发生

复制步骤:

  • 隐姓埋名
  • 打开开发工具并转到概要文件
  • 刷新页面
  • 单击两次
    Toggle
    (现在您可以再次在屏幕上看到
    Nothing
  • 拍摄堆快照
  • 在过滤器中写入'leak',这样您就可以看到
    LeakObject
    在不应该存在时仍然存在
  • 它应该是这样的:


    有人能帮忙/解释一下吗?

    一切正常, 执行步骤后,我在快照中未看到任何泄漏对象

    您可以将以下代码添加到link函数中,以查看该指令是否正在被销毁

    控制器和指令在销毁之前发出一个事件。在这里,您有机会拆除插件和侦听器,并执行垃圾收集。 订阅('$destroy',…)事件上的$scope.$


    你是说你不能重现这个问题,可能是操作系统/浏览器的问题。在OSX优胜美地上运行Chrome39.0.2171.71的我,和我交谈过的其他开发者也是如此。我知道指令正在被销毁,这就是它看起来像内存泄漏的原因。传递给
    $on(“$destroy”
    的函数被执行的事实并不能真正证明指令正在被“销毁”也不是说没有内存泄漏。虽然没有说有内存泄漏,但我自己没有调查过。你是对的,触发“$destroy”事件的事实证明Angular的流按预期工作,应该删除指令和它的作用域。我认为行new Foo().bar({});new Foo().bar($scope);在全局上创建对象,这可能是导致泄漏的原因。@Moran“”触发“$destroy”事件的事实证明Angular的流按预期工作,应删除该指令及其作用域“-如果存在泄漏,即使触发了
    “$destroy”
    ,GC也无法收集指令及其范围,这就是泄漏。显然,这在Windows 8中不是问题,Chrome 42无法在Ubuntu15/Chome上重现该问题
    $scope.$on('$destroy',function(){
      //$scope.memoryThatLeaks = null;
      alert('!');
     });