1'use strict'; 2const assert = require('assert'); 3const { GCProfiler } = require('v8'); 4 5function collectGCProfile({ duration }) { 6 return new Promise((resolve) => { 7 const profiler = new GCProfiler(); 8 profiler.start(); 9 setTimeout(() => { 10 resolve(profiler.stop()); 11 }, duration); 12 }); 13} 14 15function checkGCProfile(data) { 16 assert.ok(data.version > 0); 17 assert.ok(data.startTime >= 0); 18 assert.ok(data.endTime >= 0); 19 assert.ok(Array.isArray(data.statistics)); 20 // If the array is not empty, check it 21 if (data.statistics.length) { 22 // Just check the first one 23 const item = data.statistics[0]; 24 assert.ok(typeof item.gcType === 'string'); 25 assert.ok(item.cost >= 0); 26 assert.ok(typeof item.beforeGC === 'object'); 27 assert.ok(typeof item.afterGC === 'object'); 28 // The content of beforeGC and afterGC is same, so we just check afterGC 29 assert.ok(typeof item.afterGC.heapStatistics === 'object'); 30 const heapStatisticsKeys = [ 31 'externalMemory', 32 'heapSizeLimit', 33 'mallocedMemory', 34 'peakMallocedMemory', 35 'totalAvailableSize', 36 'totalGlobalHandlesSize', 37 'totalHeapSize', 38 'totalHeapSizeExecutable', 39 'totalPhysicalSize', 40 'usedGlobalHandlesSize', 41 'usedHeapSize', 42 ]; 43 heapStatisticsKeys.forEach((key) => { 44 assert.ok(item.afterGC.heapStatistics[key] >= 0); 45 }); 46 assert.ok(typeof item.afterGC.heapSpaceStatistics === 'object'); 47 const heapSpaceStatisticsKeys = [ 48 'physicalSpaceSize', 49 'spaceAvailableSize', 50 'spaceName', 51 'spaceSize', 52 'spaceUsedSize', 53 ]; 54 heapSpaceStatisticsKeys.forEach((key) => { 55 const value = item.afterGC.heapSpaceStatistics[0][key]; 56 assert.ok(key === 'spaceName' ? typeof value === 'string' : value >= 0); 57 }); 58 } 59} 60 61async function testGCProfiler() { 62 const data = await collectGCProfile({ duration: 5000 }); 63 checkGCProfile(data); 64} 65 66module.exports = { 67 collectGCProfile, 68 checkGCProfile, 69 testGCProfiler, 70}; 71