關于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]);
新聞熱點
疑難解答