【问题标题】:React JS memory leak with periodic calculations using setInterval使用 setInterval 定期计算 React JS 内存泄漏
【发布时间】:2020-10-29 13:19:38
【问题描述】:

我正在尝试定期运行计算(每 5 秒)并使用 setInterval 计时器使用计算值更新组件的状态。我所看到的是updateCalculation() 函数确实 每 5 秒被调用一次,但是当使用 Chrome 开发工具监控内存使用情况时,它只会在setInterval 的每次调用中不断增长。内存似乎永远不会被释放。

快照 1:
快照 2:

定期运行计算可能的解决方法是什么? 我对 React 还是很陌生,真的不确定我做错了什么。

class MyComponent extends React.PureComponent {
    constructor(props) {
        super(props);
        this.state = {
            calculated: []
        };
    }

    componentDidMount() {
        this.calculationUpdater = setInterval(() => this.updateCalculation(), 5000);
    }

    componentWillUnmount() {
        clearInterval(this.calculationUpdater);
    }

    // Memory leak here
    // The function that gets called by setInterval to calculate data and update the state
    updateCalculation() {
        let data = [];

        for (let i = 0; i < 60000; i++) {
            data.push({x: i, y: i, z: i});
        }

        this.setState({
            calculated: data
        });
    }

    render() {
        return (
            <React.Fragment>
                <Child calc={this.state.calculated} />
            </React.Fragment>
        );
    }
}

目前我没有对Child 组件做任何特别的事情。这是它的样子:

class Child extends React.PureComponent {

    render() {
        return (
            <div></div>
        );
    }
}

【问题讨论】:

  • 如果你在 React 旁边使用setInterval,你可能做错了,你肯定做错了。了解 React 如何通过状态管理 DOM 更新(实际上非​​常简单,React 官方文档也很棒)。
  • @NinoŠkopac 我实际上是基于这里的“时钟”教程:reactjs.org/docs/…
  • 孩子发生了什么事?我不认为答案在上面,因为这本身是不可重现的。
  • @PavlosKaralis 我目前没有在子组件中做任何特别的事情。请查看我更新的问题。

标签: javascript reactjs


【解决方案1】:

编辑:查看以下帖子:Does JavaScript setInterval() method cause memory leak?

您没有清除间隔,因为您没有正确设置或读取状态。因此,如果您的组件不断被挂载和卸载,您可以设置一个新的时间间隔,但不要在卸载时清除该时间间隔。

this.calculationUpdater = setInterval(() => this.updateCalculation(), 5000);

这应该是

const calculationUpdater = setInterval(() => this.updateCalculation(), 5000);
console.log(calculationUpdater )
this.setState({calculationUpdater : calculationUpdater})

你访问的状态如下:

console.log(this.state.calculationUpdater);
clearInterval(this.state.calculationUpdater);

【讨论】:

  • 我通过存储和清除状态间隔来尝试您的示例,但不幸的是我仍然遇到同样的问题。
  • 我已经用调试语句编辑了我的答案。您能否检查您的控制台并确认 console.logs 的输出是相同的。您还应该能够看到在您的控制台中调用了多少次 setInterval() 方法。它会一直被调用吗?
  • 是的,setInterval() 方法确实每 5 秒调用一次。 componentWillUnmount() 不会被执行。我相信问题在于我只清除了componentWillUnmount() 中的间隔。问题是这个应用程序将运行 天 并且组件实际上不会被卸载,因此setInterval() 的内存不会被清除。
  • 只有一个 setInterval 实例在运行,因为它是在 componentDidMount 而不是 componentWillUpdate 中调用的。它的设置与 React 文档中的示例完全相同。
  • 查看我的回答中的帖子,该帖子解释了您在此处观察到的情况。
【解决方案2】:

我唯一能建议的就是尝试从 PureComponents 切换到 Components;我注意到对于 PureComponents,我的初始快照比较滞后,但无论哪种方式,我的结果都不像你的那样。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-07-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-08
    • 2019-03-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多