我使用画布生成大量图像,此过程在生成 5000 张图像时消耗 6GB RAM。不幸的是,处理完成后内存没有被释放。尽管对我的代码进行了多次审查并尝试了各种可能的解决方案,但问题仍然存在。我尝试过的方法之一是使用“无效”方法。为了写入图像,我使用了画布流而不是缓冲区,因此需要在循环内重新初始化画布。但是,这种方法似乎会导致内存泄漏问题。我正在寻求有关如何处理和解决此问题的指导。
这是我的代码
let tempDnaContainer = JSON.parse(dnaContainer);
const saveBuffers = [];
for (let i = 0; i < tempDnaContainer.length; i++) {
const newDna = tempDnaContainer[i];
let canvas = createCanvas(format.width, format.height);
let ctx = canvas.getContext("2d");
ctx.imageSmoothingEnabled = format.smoothing;
await drawElements(canvas, ctx, newDna.attributes, i);
let stream = canvas.createPNGStream();
const filePath = `${buildDir}/images/${i}.png`;
let writeStream = fs.createWriteStream(filePath);
saveBuffers.push(
new Promise((resolve, reject) => {
pipeline(stream, writeStream, (error) => {
stream = null;
writeStream = null;
if (error) {
console.error("Error saving buffer to file:", error);
reject(error);
} else {
resolve();
}
});
})
);
stream = null;
writeStream = null;
}
await Promise.all(saveBuffers);
tempDnaContainer = null;
imageObjects = {};
这是我的drawElements代码
const drawElements = (canvas, ctx, elements) => {
elements.forEach((element) => {
const { layer } = element;
let img = imageObjects[element.loadedImage];
// Only create a new image object if it doesn't exist
if (!img) {
img = new Image();
img.onload = () => {
ctx.drawImage(img, layer.posX, layer.posY, layer.width, layer.height);
imageObjects[element.loadedImage] = null; // Dereference image from cache
img.onload = img.onerror = null; // Remove event handlers
img = null; // Dereference local reference
};
img.onerror = (e) => {
console.error(`${e}: ${element.loadedImage}`);
imageObjects[`${element.loadedImage}`] = null; // Dereference image from cache
img.onload = img.onerror = null; // Remove event handlers
img = null; // Dereference local reference
};
SetSource.call(img, `${element.loadedImage}`);
} else if (img.complete) {
ctx.drawImage(img, layer.posX, layer.posY, layer.width, layer.height);
imageObjects[element.loadedImage] = null; // Dereference image from cache
img = null; // Dereference local reference
}
});
// Dereference elements and ctx after use
elements = null;
// ctx = null;
};
你找到解决办法了吗?我没有生成与您一样多的图像,但我确实看到 rss 随着时间的推移而增加,而我的堆仍然很小。我发现一个线程提到了字体未发布的 C++ 问题。但这似乎与您的问题无关。