我注意到我们的节点应用程序在一天左右后内存耗尽。内存被每分钟左右运行一次的作业所消耗,因为这几乎是目前唯一发生的事情。当我在机器上本地运行应用程序时,我可以看到应用程序也达到了内存上限,然后垃圾收集开始进行。
在 heroku 上,它似乎超出了我们的 1G RAM 实例的内存上限,并且 GC 没有启动。我想知道是否是因为节点配置的内存限制高于实际的 Dyno。
重述:herkou 上的 node.js 内存限制是否与 Dyno 内存限制绑定?
答案1
这是 heroku 的回复。看来您需要更改配置,不能使用现成的配置。
嗨,斯坦,
感谢您链接到这些文档;我需要更新该终端示例,因为我最近已使喋喋不休的 WEB_CONCURRENCY 输出静音。我们在添加该功能时添加了日志记录,这样人们就不会对这些新变量侵入他们的环境感到惊讶。
要查看应用程序的值,您可以运行:
$ heroku run 'echo $WEB_MEMORY, $WEB_CONCURRENCY' 但是,我要澄清的是 - 这些值仅用于确定集群节点应用程序应运行多少个并发进程,而且只有当您选择在代码中使用 WEB_CONCURRENCY 值时才存在。它们根本不会影响节点二进制文件或其默认内存分配或垃圾收集,它们是从 nodejs.org/dist 下载的完全标准的 vanilla 版本:
https://devcenter.heroku.com/articles/node-concurrency#tuning-the-concurrency-level V8 使用贪婪和懒惰的方法进行垃圾收集。此外,V8 默认假设您有大约 1.5 GB 的内存可供使用(超过 2X dyno 的 1 GB 限制)。如果您有兴趣更改节点的默认内存行为,则有几种选择:
当内存超过设定的限制时,手动触发 GC(https://simonmcmanus.wordpress.com/2013/01/03/forcing-garbage-collection-with-node-js-and-v8/)
将 max_old_space_size 设置为低于默认值(例如,node --max_old_space_size=960)。v8 源中的几个指标与 max_old_space_size 相关联,因此这可以使 gc 更加激进。缺点是,如果您超过该值,即使只超过一个字节,您的程序也会崩溃。
将 gc_global 设置为 true 以强制始终进行全局收集(默认为 false - 请记住,全局收集比默认的多阶段收集慢)。
将 nolazy_sweeping 设置为 true,这也使得 gc 更加激进。
请记住,如果单节点进程的内存超过 1 GB,最佳做法是将该进程拆分为多个工作进程:
https://github.com/joyent/node/wiki/FAQ#what-is-the-memory-limit-on-a-node-process 干杯,亨特