关于nodeJS垃圾回收机制的讲解文章很多,这里我就不再重复,下面记录了一下我在工作中遇到的问题。nodejs 在64位电脑可用内存为1.4G,这是V8的内存机制决定的,目前我司所用版本比较陈旧为V4.4.3,这个版本的垃圾回收并不是做的很好,只要堆空间内存还有可用分配的就会一直分配,但是不用的空间并不会短时间内回收,除非已经分配不了新的空间才会出发垃圾回收,这样就导致当运行了占用空间比较大的代码之后,对大对象进行值空之后依然占用着堆空间,造成内存虚高,下面代码为《深入浅出nodejs》里的一段测试代码
var showMem = function(){ var mem = PRocess.memoryUsage(); var format = function(bytes){ return (bytes / 1024 / 1024).toFixed(2) + ' MB'; }; console.log('Process: heapTotal ' + format(mem.heapTotal) + ' heapUsed ' + format(mem.heapUsed) + ' rss ' + format(mem.rss)); console.log('-----------------------------------------------------------');};var useMem = function(){ var size = 20 * 1024 * 1024; var arr = new Array(size); for(var i = 0; i < size; i++){ arr[i] = 0; } return arr;};var total = [];for(var j = 0; j < 5; j++){ showMem(); total.push(useMem());}total = null;setInterval(showMem, 5000);当运行这段代码时如果不做其他的操作,几个小时后也不会等到垃圾回收,这如果算个bug的话那么nodejs的最新版本已经修复。如果你用的版本是V6以后的版本(之前的没有测试)那么再来执行这段代码,几分钟后内存就会得到释放。如果很不幸你所在的公司跟我一样用的是很老旧的版本,那么只有自己动手进行垃圾回收了,要主动进行垃圾回收首先就是在node的启动参数中加上V8的一个参数即启动命令为 node --expose-gc,然后就可以在自己的代码里调用global.gc()进行垃圾回收了,比如在上面的代码中,total=null后面加上这个函数就会立即进行垃圾回收,堆空间也得到立即释放。如果你在代码中开启了子进程,而子进程要主动进行垃圾回收,那么在生成子进程的代码中同样也加如--expose-gc参数即可 如:
var child =require('child_process');
var childProcess = child.spawn('node', ['--expose-gc',myDir]);
新闻热点
疑难解答