我的网站是非常标准的ecom网站,它不是JS支持的独立应用程序或任何东西,它只是一个使用JS标准内容的网站,以及一些jquery插件来做一些事情。
我正在尝试在我的网站上进行一些JS内存评估。我通过查看Chrome任务管理器和堆快照来完成此操作。
首次加载时,我的网站在任务管理器上位于35MB(即35,000K)到40MB之间。如果我同时打开其他网站的多个标签,则这是所有标签中最大的标签。 如果我刷新页面它会跳到55-60,另一次刷新会看到它跳到65-70MB。
在工作流程的常规页面上,它在45-65之间波动(有时75,取决于您正在做的事情)。单击并在页面之间执行工作流程会看到内存跳转到85-100,并在您继续浏览网站时增加。
我试过做一些事情,比如检查:
我需要更深入地寻找循环引用或闭包问题。
堆快照没有透露太多,大多数顶级列表是(数组),(字符串),(系统)。快照位于4.8MB,5.1MB,5.8MB,6.8MB之间并且增加。
结果我有几个问题:
How do I understand the different metrics between snapshot memory and task manager memory
Are there any good tutorials (apart from the ones on the Google Developers site)?
How much memory is considered acceptable? Given in the task manager my site is always the highest?
Do I have a memory leak? Apart from the steps I've described above (which I haven't found anything concrete from) is there any other ways I can find leaks?
Can you suggest any tools apart from the Chrome Dev Tools (a lot of the tools mentioned on Google for Firefox are not compatible with the latest version, eg: Leak Monitor for FF)
作为旁注,我的大部分功能都是低调操作,不超过200ms(基于CPU配置文件)。什么是我应该瞄准的好基准?是200ms高?
答案 0 :(得分:36)
你所描述的不是内存泄漏,它是Chrome知道的垃圾,只要Chrome决定它的时间就会被删除。为了解释这一点,让我们仔细看看你所描述的场景。
到目前为止,一切都很好 - 一切都与你描述的一模一样。
然而,将光标保持活动状态半分钟,或者转到另一个标签页,您会发现我们的“标签:谷歌”上有大量的内存使用量下降。这是为什么?那里发生了什么?谁为我们清理了'泄露'的记忆?
为了调查这一点,让我们重复我们到目前为止所做的事情,以便'Tab:google'再次使用大量内存。然后,打开Chrome开发者工具并开始在“时间轴”标签上进行录制。之后,让我们更改一个标签几秒钟,当内存下降停止'记录'在'时间轴'上。你应该最终得到这个:
在录制的最后几秒钟,出现了神秘的'GC Events'。恰好在内存发布的同时。巧合?不。
GC代表Garbage Collector。它是一种“尝试回收垃圾或由程序不再使用的对象占用的内存”的机制。所以事实证明我们的标签的内存被垃圾污染了,GC一直能够摆脱这些垃圾(你甚至可以使用'时间轴'标签底部的按钮强制进行垃圾收集)。那为什么决定不呢?为什么它等待我们停止与页面交互或更改标签?
简短的回答是垃圾收集必须在任何工作完成之前“冻结”所有脚本的执行。此外,执行可能需要大量的CPU时间。这可能会导致延迟,动画不稳定,控件无响应等。这就是为什么Chrome会等待正确的时刻来调用垃圾回收。而最好的时刻就是用户不看的时候。
另外,请注意'GC Events'是串联的,其中总有几个中间有短暂的休息时间。这些中断用于执行“普通”JavaScript,使垃圾收集不太明显。
再次查看此帖子的前两个屏幕截图中的“JavaScript内存”标签。您会注意到此列包含两个数字。第一个是“为JavaScript VM保留的内存” 堆“,另一个是”有多少内存活(可达)对象 包含“(source)。在对应用程序进行基准测试时,您应该只担心第二个值,其余部分将由GC处理。
可能发生真正的JavaScript泄漏,即。在网络聊天应用程序中。如果随着时间的推移,它将使用越来越多的“实时”内存,同时始终只显示最后10条消息然后,我们可以谈论泄漏。这种泄漏最终会导致标签(或浏览器)崩溃。
对于在页面上运行的脚本,重新加载页面(或转到其他位置)等同于在ANSI C应用程序运行时重新启动计算机。之后,您应该考虑脚本分配的所有内存消失。实际上,在重新加载页面后可能不会立即发生的唯一原因是浏览器正在等待正确的时刻进行清理。而且,作为Web开发人员,您不应该担心它。
答案 1 :(得分:1)
如果您仍然认为您的网页漏洞,可以使用this question中的答案来追踪泄露的对象。