问题描述
我的网站是非常标准的ecom网站,它不是JS支持的独立应用程序或其他任何东西,它只是一个使用JS进行标准操作的网站,以及一些jquery插件来做一些事情.
My site is pretty standard ecom site, it isn't a JS backed standalone app or anything, it's just a site which uses JS for standard stuff, as well as some jquery plugins to do a few things.
我正在尝试在我的网站上进行一些JS内存评估.我是通过查看Chrome任务管理器并通过堆快照来完成此操作的.
I'm trying to do some JS memory evaluation on my site. I've done this by looking at the Chrome Task Manager and through Heap Snapshots.
Initailly,我的网站首次加载时在任务管理器上位于35MB(即35,000K)到40MB之间.如果我同时打开其他网站的多个选项卡,则这是所有选项卡中最大的.如果我刷新页面,它会跳到55-60,再次刷新会看到它跳到65-70MB.
Initailly my site on first load sits between 35MB (i.e 35,000K) and 40MB on the task manager. This is the largest of any tab, if I have several tabs of other websites open at the same time.If I refesh the page it jumps up to 55-60, another refresh sees it jump to 65-70MB.
在工作流程的正常页面上,它会在45-65之间波动(有时是75,具体取决于您的工作).单击并在页面之间执行工作流程,可以看到内存跃升到85-100,并且随着您继续浏览该站点而增加.
On a normal page in a workflow, it fluctuates between 45-65 (sometimes 75 depending on what you're doing). Clicking around and doing the workflow from page to page sees the memory jump up to 85-100, and increases as you continue through the site.
我试图做一些检查,例如:
I've tried to do a few things like check for:
- 已确定节点
- 堆快照和看着三角洲
- amix的MemoryLeakChecker检查对象的大小
我需要更深入地研究循环引用或关闭问题.
I'd need a deeper dive to look for circular references or closure problems.
堆快照显示的不多,大多数列表是(数组),(字符串)和(系统).快照位于4.8MB,5.1MB,5.8MB,6.8MB之间,并可以增加.
Heap snapshots don't reveal much, most of the top lists are (array), (string), (system). The snapshots sit between 4.8MB, 5.1MB, 5.8MB, 6.8MB and increase.
结果我有几个问题:
-
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)
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高吗?
As a side note, most of my functions are low key operations, and don't exceed 200ms (based on a CPU profile). What is a good benchmark I should be aiming for? Is 200ms high?
推荐答案
您所描述的不是内存泄漏,而是Chrome知道的垃圾,只要Chrome决定是时候就将其删除.为了解释这一点,让我们仔细看一下您所描述的场景.
What you are describing is not a memory leak, it's a garbage that Chrome knows of and that will be removed whenever Chrome decides it's time to do it. To explain this, lets have a closer look at the scenario you have described.
- 首先让我们打开一个新的隐身窗口(以确保浏览器扩展名不会影响我们的搜索结果)并导航到google.com.
- 然后,打开任务管理器"并启用"JavaScript内存"列(通过右键单击任务管理器"窗口).我们需要此列,以确保我们将要泄漏"的内存实际上是由JavaScript分配的.我们最终得到这样的东西:
- 现在,正如您所建议的,我们应该重新加载页面几次,并观察标签页的存储空间不断增加:
到目前为止,一切都很好-一切都按照您的描述进行.
So far, so good - everything works exactly as you described it.
但是,将光标置于非活动状态半分钟,或转到另一个选项卡,您会在我们的"Tab:google"上看到大量的内存使用下降.这是为什么?那里发生了什么?谁为我们清理了泄漏"的记忆?
However, lave your cursor inactive for half a minute, or go to another tab and you will observe a huge memory usage drop on our 'Tab:google'. Why is that? What happened there? Who cleaned up our 'leaked' memory for us?
要对此进行调查,请重复我们到目前为止所做的事情,以使"Tab:google"再次占用大量内存.然后,打开Chrome开发者工具并在时间轴"标签上开始录制.之后,让我们更改标签几秒钟,然后在内存下降时在时间轴"上停止记录".您应该以此结束:
To investigate that, lets repeat what we have done so far, so that 'Tab:google' uses a lot of memory again. Then, lets open Chrome Developer Tools and start recording on the 'Timeline' tab. After that, lets change a tab for couple of seconds and when memory drops stop 'recording' on the 'Timeline'. You should end up with this:
在我们录制的最后几秒钟,神秘的"GC Events"出现了.恰好在释放内存的同一时间.巧合?不.
In the last couple of seconds of our recording mysterious 'GC Events' appeared. Exactly in the same time when the memory was released. Coincidence? Nope.
GC代表垃圾收集器.这是一种试图回收垃圾或程序不再使用的对象所占用的内存"的机制.因此,事实证明,我们选项卡的内存已被垃圾污染,GC可以在整个时间内清除这些垃圾(您甚至可以使用时间轴"选项卡底部的按钮强制进行垃圾收集).那么为什么决定不这样做呢?为什么它等待我们停止与页面互动或更改标签?
GC stands for the Garbage Collector. It's a mechanism that "attempts to reclaim garbage, or memory occupied by objects that are no longer in use by the program". So it turns out that memory of our tab was polluted by garbage and GC was capable of getting rid of these garbage for the whole time (you can even force garbage collection using button at the bottom of the 'Timeline' tab). So why it decided not to? Why it waited for us to stop interacting with the page or change the tab?
简短的答案是,垃圾回收必须先冻结"所有脚本的执行,然后才能完成任何工作.同样,它可能需要花费大量的CPU时间来执行.这可能会导致延迟,断断续续的动画,无响应的控件等.这就是为什么Chrome等待正确的时机调用垃圾回收的原因.最好的时机是当用户不看时.
The short answer is that garbage collection has to 'freeze' the execution of all scripts before any work can be done. Also, it can take significant amount of CPU time to execute. This can result in lag, choppy animations, unresponsive controls etc. That's why Chrome waits for the right moment to call the garbage collection. And the best moment to do it is when user is not looking.
此外,请注意"GC事件"是串联的,它们之间总是有短暂的中断.这些中断是为了让常规" JavaScript执行以使垃圾回收变得不那么明显.
In addition, please note that 'GC Events' come in series, there are always couple of them with short breaks in between. These breaks are meant for 'normal' JavaScript to execute making the garbage collection less noticeable.
再次查看本文顶部两幅屏幕快照中的"JavaScript Memory"选项卡.您会注意到该列包含两个数字.第一个是为JavaScript VM保留的内存"堆",另一个是有多少个内存活动(可访问)对象包含"(源).何时对应用程序进行基准测试时,您只需要担心第二个值,其余的将由GC处理.
Take a look at "JavaScript Memory" tab at the top two screenshots in this post again. You will notice that this column contains two numbers. First one is memory "reserved for JavaScript VMheap", the other one is "how much memory live (reachable) objectscomprise" (source). When benchmarking your applications you should worry only about the second value, all the rest will be handled by GC.
可能发生真正的JavaScript泄漏,即.在网络聊天应用程序中.如果随着时间的流逝,它将使用越来越多的实时"内存,同时始终仅显示最后10条消息,则我们可以谈论泄漏.这样的泄漏最终将导致标签页(或浏览器)崩溃.
A real JavaScript leak can happen ie. in a web chat application. If, over time, it will use more and more 'live' memory while always displaying only last 10 messages then we can talk about a leak. Such leak, will eventually crash a tab (or a browser).
对于在页面上运行的脚本,重新加载页面(或转到其他位置)等同于在运行ANSI C应用程序时重新启动计算机.之后,您应该考虑一下脚本所分配的所有内存.实际上,在重新加载页面后可能不会立即发生这种情况的唯一原因是浏览器正在等待正确的时机进行清理.而且,作为Web开发人员,您不必担心它.
For scripts running on the page, reloading the page (or going to another location) is equal to restarting your computer while your ANSI C app is running. After that, you should think about all the memory allocated by your scripts as wiped out. The only reason why, in practice, this may not happen immediately after reloading the page is that browser is waiting for the right moment to clean up. And you, as a web developer, should not be concerned about it.
这篇关于JavaScript内存和泄漏问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!