我正在尝试为AngularJS app内存泄漏找到解决方案。因为我是AngularJS世界的新手,所以我真的不知道从哪里开始以及在哪里纠正和优化我的代码。
我想先给你一些关于应用程序的描述。之后我会发布一些我可以衡量的记忆统计数据。我使用了三种诊断工具来测量已用内存:Windows(7)任务管理器,Firefox关于:内存和Firefox Extension MemChaser。
Windows任务管理器
Firefox使用的内存每小时增加50 - 100 MB。
约:存储器
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
MemChaser 0.5.2.1
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 :物理内存中存在的进程使用的内存。 iGC :最后一次垃圾收集器活动的持续时间。 CC :上一次循环收集器活动的持续时间。
这些结果非常引人注目,似乎循环收集器提供了最好的提示。如果我在没有视图的情况下运行我的应用程序(只是Ajax请求),没有任何戏剧性的事如果我禁用动态模板加载,则动态模板的版本没有明显差异。所以似乎这两个主题不是原因。
我的想法:每个Ajax请求都会创建新的作用域和DOM节点。之后可以建立DOM节点,但是具有数据的范围将可能仍然在存储器中。这可能是我的内存泄漏的原因吗?
那么我应该如何正确使用AngularJS指令,作用域和绑定来避免像这样的内存泄漏呢?
我对任何帮助都非常高兴。
托拜厄斯
答案 0 :(得分:3)
我使用AngularJS Batarang Chrome扩展程序来协助调试这些类型的问题。监控此扩展的模型和性能选项卡,以了解任何悬空或泄漏范围。确保当您不再需要特定范围时$destroy它。例如。看看如何ngRepeat does this。
来自文档:
$破坏()
从父级移除当前范围(及其所有子级) 范围。删除意味着不再调用$ digest() 传播到当前范围及其子级。删除也意味着 当前范围符合垃圾收集条件。
$ destroy()通常由诸如ngRepeat for之类的指令使用 管理循环的展开。就在范围之前 在这个范围内,广播了一个$ destroy事件 应用程序代码可以注册将提供的$ destroy事件处理程序 它有机会进行任何必要的清理工作。请注意,在 AngularJS,还有一个$ destroy jQuery事件,可以用来 在从DOM中删除元素之前清理DOM绑定。
和
当需要范围时,必须在范围上调用$ destroy() 并且它的子范围永久地与父母分离 因此停止参与模型变化检测和监听 通过调用通知。