node是v8引擎實現的,所以是v8的內存管理。涉及到的主要方法有:
process.memoryUsage(),v8.getHeapSpaceStatistics(),v8.getHeapStatistics(),os.cpus(),os.totalmem();下面這個討論,在開始討論以前先說一下v8的內存管理機制:
由於歷史原因和回收算法的限制,node在64位系統最大內存為1.4G左右,32位系統為0.7G左右,如果以1.5G內存為例,node做一次垃圾回收要50ms以上,做一次非增量式垃圾回收要1s以上,這是無法容忍的。v8里面分有兩塊新生代堆(new_heap)和老生代堆(old_heap),較為固定的放在老生代堆,容易移除的放在新生代堆,並且能有新生代到老生代轉化,並且在新生代堆又分為form空間和to空間。用空間換取cpu執行時間(同時也導致了內存無法完全使用),這兩個堆使用不同的算法進行管理。具體的算法回收流程這里不再介紹。
process.memoryUsage(),運行代碼結果如下:
rss:Resident Set Size,是進程在主存中占用的空間,這是系統給node分配內存的一個子集。它包括堆,代碼段,棧。對象,字符串存貯在堆里,變量存貯在棧里,js代碼存貯在代碼段空間。如果用buffer不斷分配內存rss會持續增加, 超過node內存限制,只是buffer內存分配機制造成的。
heapTotal,heapUsed表示v8內存使用情況,
external 表示綁定到由V8管理的JavaScript對象的C++對象的內存使用。buffer內存在rss以外分配。
可以看出默認情況下系統為node分配的內存是很小的才20M。但是隨着應用請求分配內存會不斷增加,直到達到內存限制閾值而報錯。
v8.getHeapSpaceStatistics()
這里我們只用關注new_space,和old_space就行了。說明了當下隊內存的使用情況。
v8.getHeapStatistics()
這是堆統計數據,隊內存默認是9M,可使用的內存1.4G,堆內存大小限制1.4G,已經使用的堆4M,很小的。
os.cpus()
數組里面對象的個數,代表服務器的內核數,nice是linux特有的window總是0,
IRQ:Interrupt ReQuest cpu中斷請求。
SYS:CPU花了多少比例的時間在內核空間運行。分配內存、IO操作、創建子進程……都是內核操作。這也表明,當IO操作頻繁時,System參數會很高。
user:cpu在用戶代碼上話費的時間。
Idel:CPU處於空閑狀態時間比例。在計算機中,讀寫磁盤的操作遠比CPU運行的速度要慢,CPU負載處理數據,而數據一般在磁盤上需要讀到內存中才能處理。當CPU發起讀寫操作后,需要等着磁盤驅動器將數據讀入內存,從而導致CPU 在等待的這一段時間內無事可做。CPU處於這種等待狀態的時間由idel參數來衡量。
一般對node進行性能和內存監控都是以這幾個函數為基礎的。所以深入了解node的內存原理以及這幾個函數是做好node性能監控的必要條件。