electron 内存泄漏排查
分享 electron 内存泄漏排查并修复 - 原因竟然是 console.log
打印了内存 buffer
一、通过任务管理器查看内存是否自动回收
先了解都有哪些进程 - 请查看electron-默认有几个进程
- 打印 主进程 id
js
console.log("[main Process ID:]", process.pid);
console.log("[main Process Type:]", process.type);
- 打印渲染进程 id
js
newWindow.webContents.on("did-finish-load", () => {
console.log(`[newWindow ${id} is ready]`);
// 输出渲染进程的 PID
const rendererPID = newWindow.webContents.getOSProcessId();
console.log(`Renderer process ID for window ${id}: ${rendererPID}`);
});
- 任务管理器观察对应的进程 id 的内存情况 来分析时哪一个进程出现了内存增长没有回收的问题
二、通过不断重复操作 查看对应的进程是否出现只增不减的情况
找到对应的进程 - 出现只增不减的情况
通过增加、或减少代码来判断是那一段代码出现了问题
警告
特别注意 console.log
是会导致内存泄漏的
请判断下面的代码哪一行可能出现内存泄漏?
js
const { contextBridge, ipcRenderer } = require("electron");
const sharedMemory = require("../shared_memory/index.js");
window.electronAPI = {
getImageData(length, mySharedMemoryKey) {
console.time("读取图片完整耗时");
console.time("创建或者打开内存");
sharedMemory.createOrOpenSharedMemory(mySharedMemoryKey, length);
console.timeEnd("创建或者打开内存");
console.time("读取内存");
const imageData = sharedMemory.readFromSharedMemory(mySharedMemoryKey);
console.log("mySharedMemoryKey", mySharedMemoryKey);
console.log("imageData", imageData);
console.timeEnd("读取内存");
console.time("关闭内存");
sharedMemory.closeSharedMemory(mySharedMemoryKey);
console.timeEnd("关闭内存");
console.log("imageData", imageData.length, Date.now());
console.timeEnd("读取图片完整耗时");
return imageData;
},
};
答案
7 行、13 行和 16 行。
第 7 行:
sharedMemory.createOrOpenSharedMemory(mySharedMemoryKey, length);
- 如果共享内存没有正确关闭或释放,可能导致内存泄漏。需要确保
createOrOpenSharedMemory
正确管理资源,并且关闭操作在任何情况下都会执行。
- 如果共享内存没有正确关闭或释放,可能导致内存泄漏。需要确保
第 13 行:
const imageData = sharedMemory.readFromSharedMemory(mySharedMemoryKey);
- 如果从共享内存读取的数据量很大,并且在日志中输出整个对象,可能导致内存泄漏,尤其是
console.log
会保留对大数据对象的引用,直到垃圾回收器回收该引用。
- 如果从共享内存读取的数据量很大,并且在日志中输出整个对象,可能导致内存泄漏,尤其是
第 16 行:
console.log("imageData", imageData);
- 在控制台输出大量数据(特别是
imageData
是大对象时)可能导致内存泄漏,因为控制台会保留对数据的引用,使垃圾回收无法及时回收这部分内存。
- 在控制台输出大量数据(特别是
1. 默认内存大小:
2. 重复几次后,这两个进程内存没有减少
3. 修复:删除代码中的 console.log("imageData", imageData);
js
window.electronAPI = {
getImageData(length, mySharedMemoryKey) {
console.time("读取图片完整耗时");
console.time("创建或者打开内存");
sharedMemory.createOrOpenSharedMemory(mySharedMemoryKey, length);
console.timeEnd("创建或者打开内存");
console.time("读取内存");
const imageData = sharedMemory.readFromSharedMemory(mySharedMemoryKey);
// console.log("mySharedMemoryKey", mySharedMemoryKey);
// console.log("imageData", imageData);
// console.timeEnd("读取内存");
// console.time("关闭内存");
sharedMemory.closeSharedMemory(mySharedMemoryKey);
// console.timeEnd("关闭内存");
// console.log("imageData", imageData.length, Date.now());
// console.timeEnd("读取图片完整耗时");
return imageData;
},
4. 修改后,重复几次截屏操作,几秒后,内存自动将回去了
说明内存被正常回收了!,这才是正常的应用进程