我正在尝试为 AngularJS 应用程序内存泄漏找到解决方案。因为我是 AngularJS 世界的新手,所以我真的不知道从哪里开始以及从哪里纠正和优化我的代码。
我试图先给你一些应用程序的描述。之后我会发布一些我可以测量的内存统计数据。我使用了三个诊断工具来测量使用的内存:Windows (7) Task Manager、Firefox about:memory 和 Firefox Extension MemChaser。
应用
统计数据
The memory used by Firefox increases by 50 - 100 MB per hour.
Size (MB) 20 min diff Size (MB)
JS-Main-Runtime 32 36/+113% 68
JS-Main-Runtime-GC-Heap-Committed 20 27/+135% 47
Heap-Allocated 54 29/+54% 83
Heap-Committed 63 28/+44% 91
JS-GC-Heap 31 26/+84% 57
Private 156 58/+37% 214
Resident 175 62/+35% 237
VSize 509 86/+17% 595
12:17 12:27 12:57 13:17
Resident (MB) 140 164 243 270
iGC (ms) 42 24 40 42
CC (ms) 3 53 206 286
Resident: Memory used by the process that is present in the physical memory. iGC: Duration of the last garbage collector activity. CC: Duration of the last cycle collector activity.
这些结果非常引人注目,似乎循环收集器给出了最好的提示。如果我在没有 View 的情况下运行我的应用程序(只是 Ajax 请求),则不会发生任何戏剧性的事情。如果我禁用动态模板加载,则与具有动态模板的版本没有明显区别。因此,这两个主题似乎不是原因。
我的想法:每个 Ajax 请求都会创建新的范围和 DOM 节点。之后可能会删除 DOM 节点,但带有数据的范围可能仍会保留在内存中。这是我的内存泄漏的可能情况和原因吗?
那么我应该如何正确使用 AngularJS 指令、范围和绑定(bind)来避免像这样的内存泄漏呢?
我会非常高兴任何帮助。
托拜厄斯
最佳答案
我使用 AngularJS Batarang Chrome 扩展程序可帮助调试这些类型的问题。监视此扩展程序的模型和性能选项卡,以了解任何悬空或泄漏的范围。确保当您不再需要特定范围时,您的 $destroy它。例如。看看ngRepeat does this .
从文档中:
$destroy()
Removes the current scope (and all of its children) from the parent scope. Removal implies that calls to $digest() will no longer propagate to the current scope and its children. Removal also implies that the current scope is eligible for garbage collection.
The $destroy() is usually used by directives such as ngRepeat for managing the unrolling of the loop. Just before a scope is destroyed, a $destroy event is broadcasted on this scope.
Application code can register a $destroy event handler that will give it a chance to perform any necessary cleanup. Note that, in AngularJS, there is also a $destroy jQuery event, which can be used to clean up DOM bindings before an element is removed from the DOM.
和
$destroy() must be called on a scope when it is desired for the scope and its child scopes to be permanently detached from the parent and thus stop participating in model change detection and listener notification by invoking.
关于AngularJS:如何正确使用指令、范围和绑定(bind)以避免内存泄漏?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19682593/