4

我试图找出我的 angularjs 代码是否有 memory-leak,但还没有找到。

我读过一些关于 javascript memory-leak 的文章,但它对 angularjs 应用程序没有用,因为它使用双向绑定,将大部分 DOM 操作隐藏给用户。

所以我还有一个问题:如何用 Angular 编写内存泄漏的应用程序?我们应该避免任何常见的错误模式吗?

4

3 回答 3

7

Angular 主要为您处理它,但有些地方您需要考虑内存。由于您的服务从创建到应用程序关闭时都存在,因此很容易在此类对象中占用内存。就像您实现缓存一样,您最终可能会持有对永远不会再次使用的对象的缓存引用,因此您需要一种策略来释放这些对象。

另一个地方是与 DOM 交互的指令。但是,只要您自己听$scope.$on('$destroy', function () { /* Clean up code here */ });并清理干净,就可以了。

于 2013-03-09T20:44:24.693 回答
4

如果使用 $timeout 执行不返回 null 的函数,则会发生内存泄漏。这在coffeescript 中很容易意外发生,因为它隐式返回函数最后一行的值

例如。

doSomethingEveryTenSeconds = ->
  //do something here
  $timeout(doSomethingEveryTenSeconds, 10000)
  null #prevent memory leak
于 2013-05-14T23:55:39.217 回答
1

要回答这个问题,您确实需要了解 Angular 的垃圾收集。它确实做得很好。但是,如果它认为仍然存在对某个对象的引用,或者其他东西正在引用它,那么就会出现内存泄漏。您可以使用 jQuery 或任何其他库通过 DOM 对象创建循环引用。

这是一个例子。http://plnkr.co/edit/nIt78S?p=preview

如果你打开 controllers.js,你会看到一个 jQuery$()到 Angular的$scope循环引用:

//*** CREATING MEMORY LEAK ***
$("#memory-leak").on('click', function() {
    console.log("[HomeController " + myInstance + "] click()");
    $scope.data.counter++;
});

因为 jQuery .on() 方法附加到控制器外部的 div 上,所以它永远不会被释放。您可以通过以下方式进行测试:
1) 打开控制台
2) 在主页和数据页面之间来回导航。每次执行此操作时,都会注意到创建了一个新的 Home Controller 实例。
3) 创建 3 或 4 个实例后,单击显示“内存泄漏测试”的 div。您会从上面的代码中看到 3 或 4 个控制台日志,这是内存泄漏!

于 2014-08-27T12:47:38.607 回答