尽管JavaScript使用垃圾回收进行自动内存管理,但有效的(effective)内存管理依然很重要。在这篇文章中我们将探讨分析JavaScript web应用中的内存问题。在学习有关特性时请确保尝试一下相关案例以提高你对这些工具在实践中如何工作的认识。请阅读内存 101(Memory 101)页面来帮助你熟悉这篇文章中用到的术语。注意:我们将要用到的某些特性目前仅对Chrome Canary版浏览器可用。我们推荐使用这个版本来获得最佳的工具,以分析你的应用程序的内存问题。
总体来说,当你觉得你遇到了内存泄漏问题时,你需要思考三个问题:
本小节介绍在内存分析时使用的常用术语,这些术语在为其它语言做内存分析的工具中也适用。这里的术语和概念用在了堆分析仪(Heap Profiler)UI工具和相关的文档中。
这些能够帮助我们熟悉如何有效的使用内存分析工具。如果你曾用过像Java、.NET等语言的内存分析工具的话,那么这将是一个复习。
把内存想象成一个包含基本类型(像数字和字符串)和对象(关联数组)的图表。它可能看起来像下面这幅一系列相关联的点组成的图。
一个对象有两种使用内存的方法:
当你使用DevTools中的堆分析仪(Heap Profiler,用来分析内存问题的工具,在DevTools的”Profile”标签下)时,你可能会惊喜的发现一些显示各种信息的栏目。其中有两项是:直接占用内存(Shallow Size)和占用总内存(Retained Size),那它们是什么意思呢?
这个是对象本身占用的内存。
典型的JavaScript对象都会有保留内存用来描述这个对象和存储它的直接值。一般,只有数组和字符串会有明显的直接占用内存(Shallow Size)。但字符串和数组常常会在渲染器内存中存储主要数据部分,仅仅在JavaScript对象栈中暴露一个很小的包装对象。
渲染器内存指你分析的页面在渲染的过程中所用到的所有内存:页面本身的内存 + 页面中的JS堆用到的内存 + 页面触发的相关工作进程(workers)中的JS堆用到的内存。然而,通过阻止垃圾自动回收别的对象,一个小对象都有可能间接占用大量的内存。
一个对象一但删除后它引用的依赖对象就不能被GC根(GC root)引用到,它们所占用的内存就会被释放,一个对象占用总内存包括这些依赖对象所占用的内存。
GC根是由控制器(handles)组成的,这些控制器(不论是局部还是全局)是在建立由build-in函数(native code)到V8引擎之外的JavaScript对象的引用时创建的。所有这些控制器都能够在堆快照的GC roots(GC根) > Handle scope 和 GC roots >Global handlers中找到。如果不深入了解浏览器的实现原理,在这篇文章中介绍这些控制器可能会让人不能理解。GC根和控制器你都不需要过多关心。
有很多内部的GC根对用户来说都是不重要的。从应用的角度来说有下面几种情况:
注意:我们推荐用户在创建堆快照时,不要在console中执行代码,也不要启用调试断点。
内存图由一个根部开始,可能是浏览器的window
对象或Node.js模块Global
对象。这些对象如何被内存回收不受用户的控制。
原文:http://www.cnblogs.com/abapscript/p/4840470.html