1. 内置支持
1.1 v8.writeHeapSnapshot 主动函数调用 11.13.0
这个使用场景比较广泛了,可以写一个接口,让后调用接口后,执行这个函数。
也可以在某些事件监听里面触发。
也可以定时触发。
1.2 --heap-prof 命令行选项 12.4.0
开启后,默认在主动退出程序时,会生成快照,异常退出无法生成。
可选配置
--heap-prof-dir 生成目录
--heap-prof-name 生成名称
--heap-prof-interval 指定 --heap-prof 生成的堆分析文件的平均采样间隔(以字节为单位)。默认为 512 * 1024 字节。
1.3--heapsnapshot-signal=signal 12.0.0
触发快照的信号,可以自定义控制生成时机
虽然名为 "kill",但这个命令实际上是用来向进程发送信号的通用工具。它不仅仅用于终止进程,还可以发送各种其他信号。IGKILL (9):这个信号确实会终止进程。但还有许多其他信号不会终止进程(但是需要注意的是k8s内监听到未处理的SIGUSR信号会直接 kill掉进程,导致 pod重启),如 SIGUSR1, SIGUSR2 等。
同样的发送信号,可以自己手动监听一下SIGUSR2, 或者写一个接口。 接口可以更好的自定义生成时机和规则。
另外注意,通过信号发送时注意,一些node的库也会发送 SIGUSR2 信号。比如 nuxt 的 HMR 更新,或者是 pm2 重启都会发送SIGUSR2信号。所以如果想要更加完善定制,建议自己写接口。
1.4 --heapsnapshot-near-heap-limit=max_count 命令行选项 14.18.0
当 V8 堆使用率接近堆限制时,将 V8 堆快照写入磁盘,参数max_count表示最多快照数量,接近限制后连续生成,但是不会超过设置参数
对比其他方案
-
优点
自动生成,无须采样,定时生成快照,在因为内存溢出导致程序退出时很方便。但是通常情况下,内存极速增长的情况下,往往来不及生成快照,就会内存溢出导致剩下退出。
-
缺点
无法自定义配置,生成
快照名称,快照目录, 只能生成在根目录,程序如果在容器内启动,快照可能会随着容器退出而销毁。
2. 第三方支持
2.1 node-heapdump
node-heapdump 最后更新时间为2022.8。
3. 其他
3.1 快照对于性能的影响
-
CPU 使用率暂时性飙升
- 生成快照时需要遍历整个堆内存
- 在快照生成期间,CPU 使用率会显著增加
- 通常持续时间取决于堆内存大小,一般在几秒到几十秒不等
-
内存占用临时增加
- 生成快照时需要额外的内存空间来存储快照数据
- 快照大小通常与当前堆内存使用量相当
- 可能导致内存使用量短暂翻倍
-
服务响应延迟
- 由于 JavaScript 是单线程的,生成快照时会阻塞主线程
- 会导致请求响应时间增加
- 建议在低峰期或者使用 Worker 线程生成快照
-
I/O 影响
- 将快照写入磁盘时会产生 I/O 操作
- 可能影响其他依赖磁盘 I/O 的操作
最佳实践建议:
- 在非关键时期(如凌晨)生成快照
- 使用 Worker 线程生成快照,减少对主线程的影响
- 控制快照生成频率,避免频繁生成
- 及时清理历史快照文件,避免占用过多磁盘空间
- 在生产环境使用前,建议在测试环境评估影响
3.2 coredump方案
如果 node的快照无法生成快照,可以考虑使用coredump方案, Linux 系统在程序崩溃时的一种保护机制,它会将程序当时的内存状态、寄存器状态等信息转储到磁盘上,形成一个 core 文件。这个文件包含了程序崩溃时的完整内存映像,对于事后分析问题非常有帮助。
