当前位置:首页>鸿蒙APP>Electron鸿蒙桌面应用内存泄漏?我花了两天才找到元凶

Electron鸿蒙桌面应用内存泄漏?我花了两天才找到元凶

  • 2026-11-05 11:53:10
Electron鸿蒙桌面应用内存泄漏?我花了两天才找到元凶

Electron鸿蒙桌面应用内存泄漏?我花了两天才找到元凶

上周在鸿蒙PC上给客户演示Electron项目,刚跑起来还挺流畅,结果不到两小时,风扇就开始狂转,内存从启动时的200M直接飙到2G,页面卡得像PPT。客户在旁边盯着,我脸上挂不住,赶紧找问题——这一找就是两天。

以为是JS内存泄漏?结果方向错了

一开始我理所当然认为是渲染进程的JS内存没释放,按照以往经验用Chrome DevTools抓堆快照,对比多次快照后发现,内存增长主要不在JS堆,而在Electron的Webview部分。

我这个项目需要在页面里动态加载外部网页,所以用了不少webview标签。一开始以为和iframe一样,移除DOM就能自动销毁,结果鸿蒙上的Electron Webview完全不是这回事——它需要显式调用destroy()方法,而且还要手动移除所有事件监听器,不然垃圾回收根本收不回来。

说白了,就是没管好Webview的生命周期。

第一个坑:Webview销毁逻辑缺失

先看我一开始的错误写法:

<!-- 错误示例:没有销毁逻辑 --><divid="webview-container"></div><script>function loadExternalPage(url) {  const container = document.getElementById('webview-container');  container.innerHTML = `<webview src="{(mem.rss / 1024 / 1024).toFixed(2)}MB`,        heapUsed: `{(mem.heapTotal / 1024 / 1024).toFixed(2)}MB`,        external: `${(mem.external / 1024 / 1024).toFixed(2)}MB`      };      // 发送到渲染进程显示      if (this.mainWindow && !this.mainWindow.isDestroyed()) {        this.mainWindow.webContents.send('memory-update', log);      }      // 写入日志文件      fs.appendFileSync(        path.join(app.getPath('logs'), 'memory.log'),        JSON.stringify(log) + '\n'      );    }, this.interval);  }  stop() {    if (this.timer) {      clearInterval(this.timer);      this.timer = null;    }  }}

优化后的效果

改完这三个坑,应用重新跑起来测试:

  • 连续运行24小时,内存稳定在300M以内
  • 动态加载100次外部网页,内存增长不超过50M
  • 客户演示时再也没出现过卡顿

个人建议

说白了,Electron在鸿蒙上跑,内存管理比在Windows上要严格得多。我个人建议:

  1. 每次用Webview都要写完整的销毁逻辑,别偷懒
  2. IPC监听器一定要在窗口关闭时移除,避免累积
  3. 定期监控内存使用,发现问题早处理
  4. 鸿蒙上Webview销毁要加延迟,给系统足够时间释放进程

别等项目上线了被客户投诉才想起优化,那时候改起来就麻烦了。


本文代码遵循MIT协议,转载请注明出处。

最新文章

随机文章