堆快照后node.js的rss内存未释放



几天来,我一直在努力解决节点应用程序中的内存泄漏问题,但在我的"战斗"中,我注意到在进行堆转储后,rss内存没有释放

节点版本:

$ node --version
v12.16.2

process.memoryUsage():的堆转储输出之前

{
"rss": 108154880,
"heapTotal": 36286464,
"heapUsed": 33339600,
"external": 1472841
}

并且在堆转储输出之后:

{
"rss": 250208256,
"heapTotal": 36286464,
"heapUsed": 32413336,
"external": 31776077
}

正如你可能注意到的那样,rssexternal显著上升(我测试过,在空闲运行应用程序数小时后,它们保持在大致相同的水平(

堆转储代码:

import { getHeapSnapshot } from 'v8'
import { createGzip } from 'zlib'
import { pipeline as streamPipeline, Readable, Writable, Duplex } from 'stream'
import { promisify } from 'util'
import { createWriteStream } from 'fs'
const pipeline = promisify(streamPipeline)
/**
* @param date `Date` to use in filename
* @returns heapdump file name in format `heapdump-<date>-<time>-<pid>.heapsnapshot.gz`
*/
export default async function heapdump (
date: Date | number,
) {
if (!(date instanceof Date)) {
date = new Date(date)
}
const filename = `heapdump-${
date.getUTCFullYear() // year
}${
`${date.getUTCMonth() + 1}`.padStart(2, '0') // month
}${
`${date.getUTCDate()}`.padStart(2, '0') // day
}-${
`${date.getUTCHours()}`.padStart(2, '0') // hour
}${
`${date.getUTCMinutes()}`.padStart(2, '0') // minute
}${
`${date.getUTCSeconds()}`.padStart(2, '0') // second
}${
`${date.getUTCMilliseconds()}`.padStart(3, '0') // millisecond
}-${
process.pid
}.heapsnapshot.gz`
let heap: Readable
let gzip: Duplex
let file: Writable
await pipeline(
(heap = getHeapSnapshot()),
(gzip = createGzip({ level: 9 })),
(file = createWriteStream(filename)),
)
if (!heap.destroyed) {
heap.destroy()
}
if (!gzip.destroyed) {
gzip.destroy()
}
if (!gzip.writableEnded) {
gzip.end()
}
if (!file.writableEnded) {
file.end()
}
return filename
}

问题是:

为什么内存没有被释放?我在这里做错了什么?

实际上我注意到了这一点,但看到最终rss被清除v8.getHeapSnapshot((使rss增加了大约100MPa,但大约10-15秒后,rss恢复正常。

最新更新