Enternode-memwatch 我們需要一個跨平台的調試庫,當我們的程式可能存在記憶體流失時,它不需要裝置告訴我們,並且會幫我們找到哪裡存在泄漏。所以我們實現了node-memwatch。 它給我們提供三件東西: 一個‘泄漏’事件發射器 memwatch.on('leak', function(info) {// look at info to find out about what might be leaking});一個‘狀態’事件發射器 var memwatch = require('memwatch');memwatch.on('stats', function(stats) {// do something with post-gc memory usage stats});一個堆記憶體區分類 var hd = new memwatch.HeapDiff();// your code here ...var diff = hd.end();並且還有一個在測試時很有用處的,可以觸發垃圾收集器的功能。好吧,一共四點。1var stats = memwatch.gc();memwatch.on(‘stats’, …): Post-GC堆統計 node-memwatch能夠在任何一個JS對象分配之前,緊隨著一次完整的記憶體回收和記憶體壓縮發出一個記憶體使用量樣本。(它使用了V8的post-gc鉤子,V8::AddGCEpilogueCallback,來在每次記憶體回收觸發時收集堆使用資訊) 統計資料包括: usage_trend(使用趨勢)current_base(當前基數)estimated_base(預期基數)num_full_gc (完整的記憶體回收次數)num_inc_gc (增長的記憶體回收次數)heap_compactions (記憶體壓縮次數)min (最小)max (最大)這裡有一個展示存在記憶體泄露的應用的資料看起來是什麼樣的例子。下面的圖表隨著時間追蹤記憶體的使用。瘋狂的綠線展示了process.memoryUsage()報告的內容。紅線展示了node_memwatch報告的current_base。左下側的盒子展示了附加資訊。 注意Incr GCs非常高。那說明V8在拚命的嘗試清理記憶體。 memwatch.on(‘leak’, …): 堆分配趨勢 我們定義了一個簡單的偵測演算法來提醒你應用程式可能存在記憶體流失。即如果經過連續五次GC,記憶體仍被持續分配而沒有得到釋放,node-memwatch就會發出一個leak事件。事件的具體資訊格式是明了易讀的,就像這樣: { start: Fri, 29 Jun 2012 14:12:13 GMT, end: Fri, 29 Jun 2012 14:12:33 GMT, growth: 67984, reason: 'heap growth over 5 consecutive GCs (20s) - 11.67 mb/hr' }memwatch.HeapDiff(): 尋找泄漏元兇 最後,node-memwatch能比較堆上對象的名稱和分配數量的快照,其對比前後的差異可以協助找出導致記憶體流失的元兇。 var hd = new memwatch.HeapDiff(); // Your code here ... var diff = hd.end();對比產生的內容就像這樣: { "before": { "nodes": 11625, "size_bytes": 1869904, "size": "1.78 mb" }, "after": { "nodes": 21435, "size_bytes": 2119136, "size": "2.02 mb" }, "change": { "size_bytes": 249232, "size": "243.39 kb", "freed_nodes": 197, "allocated_nodes": 10007, "details": [ { "what": "Array", "size_bytes": 66688, "size": "65.13 kb", "+": 4, "-": 78 }, { "what": "Code", "size_bytes": -55296, "size": "-54 kb", "+": 1, "-": 57 }, { "what": "LeakingClass", "size_bytes": 239952, "size": "234.33 kb", "+": 9998, "-": 0 }, { "what": "String", "size_bytes": -2120, "size": "-2.07 kb", "+": 3, "-": 62 } ] }}HeapDiff方法在進行資料採樣前會先進行一次完整的記憶體回收,以使得到的資料不會充滿太多無用的資訊。memwatch的事件處理會忽略掉由HeapDiff觸發的記憶體回收事件,所以在stats事件的監聽回呼函數中你可以安全地調用HeapDiff方法。 在中,我們加上了堆記憶體對象分配數量排行: 下一步怎麼做 node-memwatch提供了: 準確的記憶體使用量情況跟蹤疑似記憶體流失通知堆差異比較這是跨平台的並且不要求任何額外的裝置