![](/img/trans.png)
[英]Custom Runtime node.js - Can't see my custom logs in Google App Engine
[英]Why isn't Google App engine freeing memory using Node.js
所以这篇文章是一个两部分的问题。 我正在使用实例 class F4 测试 Google 应用引擎(内存:1024 MB 和 CPU 2.4GHz,具有自动缩放功能)。 这是在 App 引擎上找到的配置文件:
runtime: nodejs10
env: standard
instance_class: F4
handlers:
- url: .*
script: auto
automatic_scaling:
min_idle_instances: automatic
max_idle_instances: automatic
min_pending_latency: automatic
max_pending_latency: automatic
network: {}
我的 Nodejs 服务器具有正常的 Post 和 Get 路由,除了提供 static 文件和从 MongoDB 获取数据之外,这些路由不会繁重。 这是使用这些路由时的 memory 使用图:
我的第一个问题是,为什么这么小的任务需要这么多内存(大约 500mb)?
我正在使用 Chrome Devtools Node.js Memory Profiler 在我的 Windows 10 机器上运行分析测试,并且它在获取这些数字时无处可取,我正在四处拍摄快照。
我的第二个问题是关于一个特定的路线,该路线采用上传的文件并使用sharp将其调整为3个不同的图像。
尽管在我的 Windows 10 机器上按预期工作,但在调整大小完成后,为什么 Memory 没有被释放?
我正在对10mb图像进行大小调整测试,该图像被转换为缓冲区,然后存储在 memory 中。 转换代码如下:
const resizeAndSave = (buffer, filePath, widthResize, transform) => {
const { width, height, x, y } = transform;
//create sharp instance
const image = sharp(buffer);
//prepare to upload to Cloud storage
const file = publicBucket.file(filePath);
return new Promise((resolve, reject) => {
image
.metadata()
.then(metadata => {
//do image operations
const img = image
.extract({
width: isEmpty(transform) ? metadata.width : parseInt(width),
height: isEmpty(transform) ? metadata.height : parseInt(height),
left: isEmpty(transform) ? 0 : parseInt(x),
top: isEmpty(transform) ? 0 : parseInt(y)
})
.resize(
metadata.width > widthResize
? {
width: widthResize || metadata.width,
withoutEnlargement: true
}
: metadata.height > widthResize
? {
height: widthResize || metadata.height,
withoutEnlargement: true
}
: {
width: widthResize || metadata.width,
withoutEnlargement: true
}
)
.jpeg({
quality: 40
});
//pipe to cloud storage and resolve filepath when done
img
.pipe(file.createWriteStream({ gzip: true }))
.on("error", function(err) {
reject(err);
})
.on("finish", function() {
// The file upload is complete.
resolve(filePath);
});
})
.catch(err => {
reject(err);
});
});
};
这个 function 对于每个图像被连续调用了 3 次,Promise.all 并没有用于防止它们为了测试而并行运行:
async function createAvatar(identifier, buffer, transform, done) {
const dir = `uploads/${identifier}/avatar`;
const imageId = nanoid_(20);
const thumbName = `thumb_${imageId}.jpeg`;
await resizeAndSave(buffer, `${dir}/${thumbName}`, 100, transform);
const mediumName = `medium_${imageId}.jpeg`;
await resizeAndSave(buffer, `${dir}/${mediumName}`, 400, transform);
const originalName = `original_${imageId}.jpeg`;
await resizeAndSave(buffer, `${dir}/${originalName}`, 1080, {});
done(null, {
thumbUrl: `https://bucket.storage.googleapis.com/${dir_}/${thumbName}`,
mediumUrl: `https://bucket.storage.googleapis.com/${dir_}/${mediumName}`,
originalUrl: `https://bucket.storage.googleapis.com/${dir_}/${originalName}`
});
/* Promise.all([thumb])
.then(values => {
done(null, {
thumbUrl: `https://bucket.storage.googleapis.com/${dir_}/${thumbName}`,
mediumUrl: `https://bucket.storage.googleapis.com/${dir_}/${mediumName}`,
originalUrl: `https://bucket.storage.googleapis.com/${dir_}/${originalName}`
});
})
.catch(err => {
done(err, null);
}); */
}
在我的 Window 10 机器上运行服务器时的堆快照是:
这些堆快照清楚地表明,使用 memory 将 10mb 图像存储在 memory 并调整其大小正在返回到我机器上的操作系统。
StackDriver 上报告的 memory 使用情况为:
这清楚地表明memory在操作完成时并没有被释放,而且非常高,从晚上8点左右开始,它上升到800mb并且从未下降。
我也尝试了 Stackdriver 分析器,但它没有显示任何高 memory 使用率,但实际上,它显示大约 55mb,接近我的 windows 机器:
因此,如果我的分析是正确的,我假设它与运行应用引擎中的实例的操作系统有关? 我没有任何线索。
更新:这是在使用图像处理路线并且一个小时不接触应用程序后从 Stackdriver 获得的最新 memory 用法:
更新 2 :根据 Travis 的建议,我在导航到路线时查看了该过程,发现 memory 的使用率略高于堆,但与应用引擎显示的相差甚远:
更新 3 :在与图 5 相同的时间间隔内使用的实例数(而 memory 的使用率很高):
更新 4:所以我尝试切换到实例 class F1(256 MB 600 MHz)看看会发生什么。 结果显示空闲时内存使用量减少,但当我处理 10mb 图像时,应用程序引擎会发送一条警告说升级内存。 (它显示了 2 个正在运行的实例)。
这使我认为这些实例无论如何都试图占用大部分可用的内存。
因此,作为上述评论和您上次更新(更新 4)的结果,我们可以意识到:
是预期的行为。
调查 Node.js 应用程序 Memory 用法的一种方法是深入了解垃圾收集器的概念。
垃圾收集器(GC)的工作是回收未被使用的对象(垃圾)占用的 memory。
在这里和这里您可以在 Node.js 中找到有关 Memory 管理和使用的信息
此外,Node.js 在认为有必要时会启动 GC。 根据这篇文章,检测可能的 memory 泄漏的想法是手动强制垃圾收集器并检查 memory 是否仍在上升。 然而,这不是一个好的做法,不建议在生产中使用,而只是作为一种诊断方法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.