【发布时间】:2020-10-11 19:36:51
【问题描述】:
我部署的应用程序有一个函数,只要调用app.get("/") 路由,或者当用户向数据库添加或删除文件时,它就会调用数据库。调用此函数时,我的 Web 主机限制了我的服务,因为它超出了我的内存分配,导致我的一个 npm 包(尖锐)出现故障,没有可用于处理图像的处理器线程。
我研究了我的网络主机提供的指标,但除了告诉我发生了错误之外,它并没有显示内存使用量有多大或在哪里。使用 Chrome DevTools 任务管理器,我可以看到实时 javascript 内存实际上确实在应用程序运行时缓慢增加,但并不比我查看过的其他网页多。
我在该领域没有导师,在对内存泄漏、导致它们的原因以及如何解决它们进行了详尽的研究之后,我感到迷茫和困惑,但我相信我已经将其范围缩小到问题的罪魁祸首。我只是不知道从这里做什么。
这里是有问题的函数:
let artWorks = [];
async function listFiles() {
artWorks = []; //clears the array if it has content
const [files] = await storage.bucket(bucketName).getFiles(); //call for url names of files in DB
files.forEach(file => { //loops through all files and pushes them to the array, separating the URL string into usable data
function splitStr(str) {
var string = str.split("/");
artWorks.push(
{
imgCategory: string[0],
subCat: string[1].replace(/-/g, ' '),
imgSrc: bucket + file.name,
thumbnail: thumbBucket + file.name.split('.')[0] + "-thumb.jpg",
alt: string[2]
});
}
var str = file.name;
splitStr(str);
});
console.log("files listed");
}
artWorks 数组是整个应用程序的关键。每个路由都使用这个数组的内容来填充 ejs 模板页面。用户添加或删除文件后,将再次调用 listFiles() 函数以重新填充数组。
我没有注意到性能下降,如果不是因为我的网络主机限制了我的内存,我永远不会知道有泄漏。请为我提供指导,希望不要过多地涉及术语,但是像我这样的新开发人员可以理解的术语。
【问题讨论】:
-
如果到处使用
artWorks,任何使用它的代码都可能因为持有“旧”数组而导致内存泄漏。制作堆快照并检查究竟是什么保留了对象。 -
Chrome devtools 测量客户端内存使用情况,这与服务器端代码无关。数组中有多少个文件?
-
@GuyIncognito 文件数量不定,但平均约为 100 个。每个文件代表数组中的一个对象,其中键:值对显示在函数中。
-
不是内存泄漏,但是将 splitStr 放入 forEach 会给内存管理器带来更多压力。您基本上会在 1 时为每个文件创建一个新函数。
-
再次,该屏幕截图显示了您的浏览器的内存使用情况。它与 Node.js 代码无关。您需要在服务器上拍摄快照。
标签: javascript node.js memory-leaks heap-memory heap-dump