内存泄露
什么是内存泄露?
应用程序不再需要占用内存的时候,由于某些原因,内存没有被操作系统或可用内存池回收。
编程语言管理内存的方式各不相同。只有开发者最清楚哪些内存不需要了,操作系统可以回收。一些编程语言提供了语言特性,可以帮助开发者做此类事情。另一些则寄希望于开发者对内存是否需要清晰明了。
JavaScript 内存管理
JavaScript 是一种垃圾回收语言。垃圾回收语言通过周期性地检查先前分配的内存是否可达,帮助开发者管理内存。换言之,垃圾回收语言减轻了“内存仍可用”及“内存仍可达”的问题。两者的区别是微妙而重要的:仅有开发者了解哪些内存在将来仍会使用,而不可达内存通过算法确定和标记,适时被操作系统回收。
JavaScript 内存泄露
垃圾回收语言的内存泄露主因是不需要的引用。理解它之前,还需了解垃圾回收语言如何辨别内存的可达与不可达。
内存泄漏排查工具
主要借助 Chrome 浏览器进行排查
Performance
- 在录制前先选中Screenshots、Memory。
- 点击 record 。
- 对页面进行操作。
- 操作结束后,停止录制。
- 通过JS Heap查看内存泄漏情况。
- 如果内存占用基本平稳,接近水平,就说明不存在内存泄漏。反之,则有内存泄漏。
Memory
Heap snapshot
当生成了第一个快照的时候,开发者工具窗口已经显示了很详细的内存占用情况。
字段解释:
- Constructor — 占用内存的资源类型
- Distance — 当前对象到根的引用层级距离
- Shallow Size — 对象所占内存(不包含内部引用的其它对象所占的内存)(单位:字节)
- Retained Size — 对象所占总内存(包含内部引用的其它对象所占的内存)(单位:字节)
将每项展开可以查看更详细的数据信息。
- 生成第一个快照,通过Summary可以查看内存占用情况。
- 切回网页进行操作。
- 再次生成一个快照,可以通过Comparison与第一个快照进行对比。
- 需要特别注意这个 #Delta ,如果是正值,就代表新生成的内存多,释放的内存少。其中的闭包项 closure ,如果是正值,就说明存在内存泄漏。
Allocation instrumentation on timeline
- Start recording heap profile
- 对页面进行操作
- 操作结束后停止录制
- 最后会生成柱状图。
- 高度表示内存大小,蓝色柱是在timeline最后还存在的内存,灰色柱是在timeline结束前已经被回收的内存。
- 可以通过 Constructor 查看哪些依然被持有