【问题标题】:Changing backgroundImage causes memory leak (Electron)更改 backgroundImage 会导致内存泄漏(电子)
【发布时间】:2020-04-24 22:19:39
【问题描述】:

我有一个具有多个背景图像但位置不同 [0..n] 的 div 元素。

图像格式为 png 格式,但为动画 (apng)。

一开始,每个位置都没有图片(背景图像:无,无,...,无)。 但是,每次我在某个位置使用动画精灵更新此属性时,缓存都会保留属性中引用的所有先前图像,并且内存会不断增加。

function test() {
  let charImg = ''
  for (let i=0; i<g.characterList.image.length; i++) {
    if (charImg !== '') charImg += ', '
    let param = '#date=' + new Date().getTime()
    charImg += 'url("./sprite.png' + param + '")'
  }

  const character = document.getElementById('character')
  character.style.backgroundImage = charImg
}

在这个例子中,我用一个简单的 onclick 事件调用 test()。每次调用都会使内存增加而不会被垃圾收集器清除。

我什至尝试从 dom 中删除 div 元素并使用新的 background-image 属性创建一个新元素,结果相同。

我什至在我的 html 中添加了以下内容:

<meta http-equiv='cache-control' content='no-cache, no-store, max-age=0, must-revalidate'>
<meta http-equiv='expires' content='0'>
<meta http-equiv='pragma' content='no-cache'>

有关信息,我需要将参数放入 url,以便每次我设置 background-image 属性时精灵都会重新加载。

对于这个地狱般的问题,是否有解决方案或替代方案?提前致谢。

Memory at the start of the app

Memory after calling test many times

【问题讨论】:

  • 您如何发现这是内存泄漏?意味着仅仅因为这个(在每次新图像加载时)内存增加不是泄漏,当系统需要内存时,它会从内存中清除未使用的图像。您是否还觉得您的应用有任何其他差异,例如变慢或其他原因
  • @mastermind 好吧,对我来说,图像“sprite.png”是 10.0Kb 大小。我向 url 添加参数的事实使精灵再次完全加载,但用于背景图像属性的前一个精灵保留在内存中,并且未被 GC 释放。所以,我认为不自然的是所有内容都保留在内存中:内存预期:只需要“sprite.png#date=_dateN_”实际结果:“sprite.png#date=_date1_”、“sprite.png#date=_date2_” , ...,"sprite.png#date=_dateN_" ("sprite.png#date=_date1_" 到 "sprite.png#date=_dateN-1_" 不需要)。我这样想错了吗?
  • @mastermind 对不起,实际上当应用程序空闲并最小化时,缓存被清除了!但是,是的,我必须最小化窗口并等待几秒钟才能发生。所以我想这本身不是内存泄漏。但是,我相信我的整个代码仍然存在内存泄漏,因为“我的项目”内存增加(长时间使用超过 30 个月)并且即使最小化也没有被清除。我通过将主 js 文件中的大部分全局变量放入变量 g 中删除了它们。该文件包括多个其他 js 文件,它们是模块。有什么想法吗?
  • @mastermind 此外,我仍然不知道单个应用程序的这 5 个进程之间有什么区别。也许它可以帮助我更好地理解原因?

标签: javascript html css electron


【解决方案1】:

这不是泄漏:)

您如何发现这是内存泄漏?意味着仅仅因为这个(在每次新图像加载时)内存增加不是泄漏,当系统需要内存时,它会从内存中清除未使用的图像。您是否还感觉到您的应用程序有任何其他差异,例如变慢或其他原因。

单个应用程序的5个进程

据我所知,电子应用程序启动 Chromium,其中一些进程和 Node.JS 服务器有一些进程。

根据我的经验,即使关闭 Electron 应用程序,它也不会从后台删除。

electron.app.once('window-all-closed', electron.app.quit);
electron.app.once('before-quit', () => {
    window.removeAllListeners('close');
});

electron and node on windows, kill a spawned process

【讨论】:

  • Pfiew,有那么一瞬间我以为我必须更换运营商。谢谢。 :)
猜你喜欢
  • 1970-01-01
  • 2021-03-23
  • 2021-09-25
  • 2014-12-08
  • 1970-01-01
  • 1970-01-01
  • 2010-09-09
  • 2011-06-16
相关资源
最近更新 更多