【问题标题】:JavaScript heap memory is constant, but the browser process private bytes are growing. Where does the memory difference come from?JavaScript 堆内存是恒定的,但浏览器进程的私有字节正在增长。内存差异从何而来?
【发布时间】:2014-07-13 08:17:58
【问题描述】:

我正在对我们的配置页面中似乎存在内存泄漏的问题进行故障排除。该页面用于更改我们服务的配置并显示健康诊断。这意味着我们定期查询服务以获取配置和检测信息(通常我们使用 30 秒的查询间隔,但为了排除故障,我以 100 毫秒的间隔查询)。我们依赖于 knockoutjs、datajs、jquery 和 spinjs。

我发现,如果我以 100 毫秒的查询间隔打开页面,Chrome 浏览器选项卡的私有字节会从大约 50MB 增长到 335MB。我有四页关于这个问题的内容,但在我的故障排除工作中我只关注其中一页。使用 chrome://memory-redirect/ 我可以看到页面(进程 id 26148)内存。

但是,JavaScript 堆内存在同一时期似乎持平,为 3.6MB。使用 Chrome 中的堆分析工具显示我所有的对象分配都是垃圾回收的。

在上图中,灰色的分配表示对象已被 GC 清理。

内存时间线也是不变的。

我还强制进行了两次 GC,并确认两次 GC 之间的文档、节点和侦听器的数量是恒定的。

我的问题是:

  1. 不属于 JavaScript 堆的进程内存在哪里使用?
  2. 鉴于我们的 JavaScript 堆内存是平坦的,那额外的内存会不会是我们的 JavaScript 代码导致的内存泄漏?

感谢大家的帮助!

【问题讨论】:

  • 控制台打开时是否启用了网络选项卡?这将为每个发出的请求保留一份请求标头、响应标头、正文等
  • @PaulS。 - 您是否暗示如果打开网络选项卡可能会导致问题?在运行显示内存使用量增加的测试时,我没有启用 Chrome 开发工具,包括网络选项卡,因为我担心它会使用大量额外内存并给我错误的结果。
  • 你有没有找到这个问题的答案?我们在 Chrome 40 中看到了相同的行为。
  • 我也看到了同样的情况。运行每秒进行大量 REST 调用的应用程序。选项卡内存随 REST 调用成比例增长,但堆大小保持大致相同。铬 40。
  • @CullyLarson - 我从来没有找到确切的根本原因。最后,我采用了宏方法,只是将页面打开了数周,以查看进程的内存会发生什么。内存最终被清理干净,并没有无限增长。它仍然太高了,我不喜欢(这是很久以前的事了,我现在不记得确切的数字了),但至少有一个限制。

标签: javascript memory memory-leaks


【解决方案1】:

您正在比较苹果和橙子 - 垃圾收集内存在子堆和整个应用程序内存中。

您已使用 Chrome 检查 JavaScript 堆并发现表明您的应用程序的 JavaScript 部分运行正常的证据。

您还使用了一个工具来监控 Chrome 本身的全局内存使用情况。这就是 Chrome 用于任何任务的所有内存,包括与您的应用程序不直接相关但与浏览器本身的功能相关的任务。

也许您发现了一个在 Chrome 内部触发内存泄漏的用例?

或者也许不是内存泄漏,而是 Chrome 使用的非垃圾收集内部堆中的内存碎片?

根据web page,Chrome 是用 C、C++、Java、JavaScript 和 Python 混合编写的。这意味着我们有用于 C 和 C++ 的确定性内存分配器以及用于 Java、JavaScript 和 Python 的三种不同类型的垃圾收集堆。坏消息:当涉及到垃圾收集时,Python 对整数的处理在内存使用方面并不是那么好(我上次检查,那是几年前,也许他们已经改进了它)。

但我已经让 Chrome 会话运行了数周而没有问题。所以我很想知道发生了什么。

您没有说您使用的是哪个操作系统,但如果您使用的是 Microsoft Windows,那么您可以使用 C++ Memory Validator 在 Chrome 运行时检查每个分配的位置(完整的调用堆栈、多少字节等)(启动来自 C++ Memory Validator 的 Chrome,加载您的应用程序,让它执行,然后转到 Memory 选项卡并单击 Refresh - 它会显示所有可以跟踪的实时分配- 任何静态链接的堆都无法跟踪,因为您没有允许它们被钩住的符号)。好的,您没有使调用堆栈可读的符号,但您仍然可以识别发生在同一个地方的分配。这可能会为您提供有关泄漏/碎片原因的线索,以便可以将其报告给 Chrome 开发人员以进行仔细查看。

您在 Firefox 中是否得到相同的行为?如果您可以使用 C++ Memory Validator 执行我建议的操作,但可以在您自己构建的 Firefox 版本上执行此操作 - 您将拥有符号和源代码并确切知道问题出在哪里。

免责声明。我是 C++ Memory Validator 的设计者。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-07-21
    • 2015-06-07
    • 2013-12-28
    • 2010-12-12
    • 1970-01-01
    • 2018-11-27
    • 2016-07-11
    相关资源
    最近更新 更多