解释 Chrome 内存工具的内存泄漏结果?

问题描述 投票:0回答:1

我很确定我有内存泄漏。当我重复执行某些操作(例如打开菜单),然后使用 3 个堆快照技巧时,总是会泄漏内存。每次的保持器都不一样。我禁用了 React Devtools 并尝试了生产构建,但仍然出现内存泄漏。

我花了两天时间试图解释结果,但我仍然不知道这意味着什么。例如。这是内存泄漏的示例:

如果有人知道以下任何问题的答案,那就太好了:

  1. 将其解释为是否正确:

    HTMLInputElement
    以某种方式引用了调用
    useContext
    的函数?

  2. 保留器中的“instruction_stream”、“previous”和“context”是什么意思?

  3. 我知道“(编译代码)”意味着它是 V8 创建函数的优化版本。然而,Chrome 似乎多次生成“useContext”的新优化版本?我多次重复了 3 堆技巧,并且“useContext”每次都在那里。

  4. 我在哪里可以找到更多关于“(代码重定位信息)”,“(代码deopt数据)”,“(源位置表)”等含义的信息?

javascript reactjs memory-leaks google-chrome-devtools
1个回答
0
投票

我也希望有一些关于内存快照中使用的所有奇怪术语的良好文档,但我不知道其中一个,所以接下来的内容主要是最好的猜测。

这是我阅读屏幕截图的方式(主要是底部):

  • 文档中有一个
    <input>
  • value
    属性是在
    react-dom.development.js
    第 1652 行定义的 getter(看一下,它实际上只是原生 getter 的包装)
  • getter 是一个函数,或者更确切地说是一个闭包,特别是它可以访问在其外部定义的变量(这就是闭包的全部意义),这就是
    context
    所指的,闭包可以访问的变量。
  • 特别是,其中一个变量称为
  • HooksDispatcherOnUpdateInDEV
    (在 React 内部定义),它又指的是 
    useContext

instruction_stream

previous
context
可能是V8源代码内部使用的单词。我在上面解释了
context
previous
肯定是一个实现细节,也许上下文被定义为嵌套上下文的链接列表,你需要更进一步。 
instruction_stream
 可能是实际编译指令的存储位置。
如果您了解 V8 如何实现的更多技术细节(我不知道),

(code relocation info)

(code deopt data)
(source position table)
 可能又会有意义。

但是这里有两个想法可以帮助您进一步进行调试:

首先,在我看来,内存泄漏不太可能仅仅是因为编译了太多代码。通常内存泄漏是由于某些实际的 Javascript 对象(或 DOM 元素)被泄漏造成的,所以我建议您尝试在内存快照中查找这些对象。

但最重要的是,

分析应用程序的生产版本,而不是开发版本

React 的开发版本很可能包含“故意”内存泄漏,例如为了使 React 开发工具正常工作,因此尝试分析它根本没有帮助。

祝你好运!

© www.soinside.com 2019 - 2024. All rights reserved.