如何避免角度应用中的内存泄漏?

时间:2013-03-09 17:26:30

标签: memory-leaks angularjs

我试图找到if my angularjs code has memory-leak,但尚未找到。

我已经阅读了一些关于javascript内存泄漏的文章,但它对于angularjs应用程序没有用,因为它使用bi-binding来隐藏大部分DOM操作给用户。

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

3 个答案:

答案 0 :(得分:7)

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

另一个地方是与DOM交互的指令。但只要你听完$scope.$on('$destroy', function () { /* Clean up code here */ });然后自己清理,你应该没事。

答案 1 :(得分:4)

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

例如

doSomethingEveryTenSeconds = ->
  //do something here
  $timeout(doSomethingEveryTenSeconds, 10000)
  null #prevent memory leak

答案 2 :(得分: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页面和数据页面之间来回导航。每次执行此操作时,请注意创建新的Home Controller实例 3)创建3或4个实例后,单击“内存泄漏测试”的div。您将从上面的代码中看到3或4个控制台日志,内存泄漏!