使用jQuery或JavaScript查找页面的内存使用情况

106

有没有办法找出一个网页或我的jquery应用程序正在使用多少内存?

这是我的情况:

我正在使用jquery前端和restful后端构建一个数据密集型的Web应用程序,该后端以JSON格式提供数据。 网页只加载一次,然后所有操作都通过ajax完成。

UI提供了一种在UI中创建多个选项卡的方法,每个选项卡可以包含很多数据。 我正在考虑限制他们可以创建的选项卡数量,但认为只有在内存使用量超过某个阈值时才限制会更好。

基于答案,我想澄清一些问题:

  • 我正在寻找运行时解决方案(不仅仅是开发人员工具),以便我的应用程序可以根据用户浏览器中的内存使用情况确定操作。
  • 计算DOM元素或文档大小可能是一个很好的估算,但它可能非常不准确,因为它不包括事件绑定,data(),插件和其他内存数据结构。

你应该调查你的Web应用程序的用户类型,以确定他们在使用你的Web应用程序时是否有内存问题。或者你自己的Web应用程序是否存在内存/性能问题? - Prutswonder
@Prutswonder:我没有遇到麻烦,只是好奇是否存在这样的工具。我认为,与其仅在选项卡上设置固定限制,使用动态方法可能更加酷炫。 - Tauren
我刚刚在问题中添加了一些额外的细节,以帮助澄清我正在寻找的是运行时解决方案,而不是构建时解决方案。 - Tauren
2
只是一个问题,如果某个东西已经被缓存了,那么它仍然会计算在内吗? - ajax333221
10个回答

81

2015更新

回顾2012年,如果您想支持所有主要浏览器的使用,这是不可能的。遗憾的是,现在这仍然是一个仅限Chrome功能(window.performance的非标准扩展)。

window.performance.memory

浏览器支持:Chrome 6+


2012答案

有没有方法可以查找网页或我的jquery应用程序正在使用多少内存?我正在寻找运行时解决方案(而不仅仅是开发人员工具),以便我的应用程序可以根据用户浏览器中的内存使用情况确定操作。

简单但正确的答案是没有。并非所有浏览器都向您公开此类数据。而且,我认为您应该放弃这个想法,因为“手工制作”的解决方案的复杂性和不准确性可能会带来更多问题。

计算DOM元素或文档大小可能是一个很好的估计,但它可能会非常不准确,因为它不包括事件绑定、data()、插件和其他内存数据结构。

如果您真的想坚持您的想法,您应该分离固定和动态内容。

固定内容不取决于用户操作(脚本文件、插件等使用的内存)
其他所有都被视为动态内容,并且在确定限制时应该是您的主要关注点。

但是没有简单的方法来总结它们。您可以实现一个“跟踪”系统来收集所有这些信息。所有操作都应调用相应的跟踪方法。例如:

包装或覆盖jQuery.data方法,以通知“跟踪”系统您的数据分配情况。

包装html操作,以便添加或删除内容也会被跟踪(innerHTML.length是最佳估算)。

如果保留大型内存对象,则还应对其进行监视。

在事件绑定方面,你应该使用 事件委托,这样也可以被视为一个相对固定的因素。

另一个使正确估计您的内存需求变得困难的方面是,不同的浏览器可能会以不同的方式分配内存(用于Javascript对象和DOM元素)。


innerHTML.length 会占用内存、RAM 或 CPU(或其他任何东西,我不知道)来进行处理吗? - mrReiha
此功能不支持IE9+或除Chrome之外的任何浏览器。Window.performance.memory仅适用于Chrome。https://docs.webplatform.org/wiki/apis/timing/properties/memory - Blunderfest
你是对的,我以为内存是导航计时标准和 window.performance 对象的一部分。旧的“支持”条目适用于该标准。在 Chrome 中,window.performance.memory 被认为是非标准扩展。 - gblazex
要通过window.performance.memory启用实时内存监视,您需要使用--enable-precise-memory-info标志启动Chrome。 - kluverua
更新:Opera 也支持此功能。来源:Mozilla。https://developer.mozilla.org/zh-CN/docs/Web/API/Performance#Browser_compatibility - HoldOffHunger

41
您可以使用 导航定时 API

导航定时是一个用于准确测量 web 性能的 JavaScript API。该 API 提供了一种简单的方式,以获取有关页面导航和加载事件的准确和详细的计时统计信息。

window.performance.memory 可以访问 JavaScript 内存使用数据。


推荐阅读


非常好的建议。谢谢你。 - MaximOrlovsky

23

这个问题已经有5年历史了,而且在此期间JavaScript和浏览器都得到了极大的发展。由于现在至少在某些浏览器中是可能的,并且当您谷歌搜索“javascript show memory usage”时,此问题是第一个结果,所以我想提供一个现代化的解决方案。

memory-stats.js: https://github.com/paulirish/memory-stats.js/tree/master

This script (which you can run at any time on any page) will display the current memory useage of the page:

var script=document.createElement('script');
script.src='https://rawgit.com/paulirish/memory-stats.js/master/bookmarklet.js';
document.head.appendChild(script);


1
这似乎是报告JS内存使用情况而不是页面内存使用情况,Chrome内置的任务管理器显示Gmail正在使用250MB,而memory-stats.js报告33.7MB。 - brandito
bookmarklet.js的github页面上没有列出许可证,因此它很可能受版权保护,是知识产权。这就在依赖该项目时留下了一定的不确定性。 - HoldOffHunger

8

我不知道有什么方法可以准确地找出浏览器使用了多少内存,但您可以基于页面上元素数量使用启发式方法。使用jQuery,您可以执行$('*').length,它将给出DOM元素的计数。不过,老实说,可能更容易进行一些可用性测试并确定支持的固定选项卡数。


3
不是个坏主意,但这不会提供有关非DOM内存(例如.data()和内存数据结构)的信息。但它可以给出一个整体权重的良好估计值,我可以利用它。 - Tauren

4

@Pablo:谢谢。我肯定会使用开发工具,但是希望能找到一些可以在运行时使用的东西,以查找每个用户浏览器中的内存使用情况。 - Tauren

3
如果您只是想进行测试,那么在Chrome中有一种通过开发者页面跟踪内存使用的方法,但不确定如何直接在JavaScript中完成。

@Zachary:谢谢。我肯定会使用开发工具,但希望能找到一个运行时分析解决方案。 - Tauren
1
如果你找到了一个,告诉我一声,我很想方便地使用它。 - Zachary K

3
我想提出与其他答案完全不同的解决方案,即观察您的应用程序速度,一旦速度低于定义的水平,就向用户显示关闭选项卡的提示,或禁用新选项卡的打开。一个简单的类可以提供这种信息,例如https://github.com/mrdoob/stats.js。 除此之外,对于这样一个密集的应用程序来说,在第一时间将所有选项卡都保留在内存中可能并不明智。例如,只保留用户状态(滚动)并在打开除最后两个选项卡以外的所有数据时加载所有数据可能是更安全的选择。
最后,Webkit开发人员一直在讨论将内存信息添加到JavaScript中,但他们已经就应该公开什么和不应该公开什么进行了多次争论。无论如何,这种信息在未来几年内可能会可用(尽管现在这些信息并不太有用)。

1

正好在我开始一个类似的项目时问得非常及时!

由于它需要更高级别的权限,因此没有准确的监视应用程序中JS内存使用情况的方法。如评论中所述,检查所有元素的数量等将是浪费时间的,因为它忽略了绑定事件等。

如果存在内存泄漏或未使用的元素持续存在,则这将是一个架构问题。确保关闭的选项卡内容完全删除,而不会有残留的事件处理程序等,将是完美的解决方案;假设已经完成,您可以在浏览器中模拟重度使用,并从内存监视中推断结果(在地址栏中键入about:memory

专业提示:如果您在IE、FF、Safari等浏览器中打开同一页面,然后在Chrome中导航到about:memory,它将报告跨所有其他浏览器的内存使用情况。很棒吧!


0
你可能想要做的是让服务器在会话中跟踪他们的带宽(发送给他们的数据字节数)。当他们超出限制时,服务器不应通过ajax发送数据,而是应发送一个错误代码,JavaScript将使用该代码告诉用户他们使用的数据太多。

@incrediman:这也是一个很酷的想法,但我认为如果不内置大量跟踪功能,它可能行不通——仅仅计算字节数是不够的。问题在于选项卡中的数据是用户将以许多不同的方式进行过滤和排序的列表。每次他们进行更改时,新数据将从服务器检索并替换当前的dom元素。此外,如果他们点击“重新加载”并开始使用全新的页面怎么办?我必须跟踪304等内容,但我打算只提供静态html,所有数据都来自REST服务。 - Tauren
这种方法没有考虑使用createElement()或remove()创建或销毁的元素,这会影响客户端内存使用。但有趣的是,它与其他答案不同(通过测量服务器端而不是客户端,您的测量结果不会改变内存使用方式,而其他答案则会)。 - HoldOffHunger

0
你可以获取 document.documentElement.innerHTML 并检查其长度。这将给出您的网页使用的字节数。
这种方法可能不适用于所有浏览器。因此,您可以将所有 body 元素包含在一个巨大的 div 中,并调用该 div 上的 innerhtml。类似于 <body><div id="giantDiv">...</div></body>

4
生成的 innerHTML 字符串长度与浏览器在呈现该 HTML 时使用的内存(例如其内部对象模型)之间的相关性不太可能是有用的。 - T.J. Crowder
那是为什么呢?我的理由是,如果一些文本被加载到浏览器中,它必须存储在内存中。因此,它确实提供了浏览器用于呈现页面的内存使用量的一定度量。 - Midhat
4
从这个角度来考虑。如果你说“我想给你一千万美元”,那么就是8个单词。另一方面,如果你说“我想在你的餐巾上打喷嚏”,那就是7个单词。第一个比第二个更有价值吗?只是8/7吗? - intuited
就内存而言,两者都包含大约30个字符,我们是在谈论数据的存储还是语义? - Midhat
1
这类似于 @tvanfosson 的建议,获取 DOM 元素的数量。您的方法可能会更准确,因为不同的 DOM 元素可能包含不同数量的文本。但它仍然无法获取有关 data()、click 手动程序、内存数据结构和对象等信息。我的应用程序使用了许多这些功能。 - Tauren
1
作用域中可能存在指向已分离的DOM节点的JS变量,这些节点不会成为文档元素的一部分。此外,您可以编写代码将一个非常长的字符串加载到变量中,消耗几GB的内存,而不影响页面上的文本。 - Josh Ribakoff

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接