我有一个非常小的集合,只调用了一个不存在的URL,从而产生了一个错误。
我在浸泡周期中对其进行迭代,每个周期都会产生大约2.9-3 MB的内存峰值,并且不会释放它。
第一次运行heapUsed后为8.8 mb,第十次运行后为20.45 mb。
每个运行周期都使用预先生成的选项集运行,如下所示:
{
"collection": "c:/workspace/postman/common/iterationExample.postman_collection",
"environment": {
"id": "3afdcf58-7ddd-71eb-ef87-c75501df3267",
"name": "SchemaValidations",
"values": [
{
"enabled": true,
"key": "some server",
"value": "some url",
"type": "text"
},
{
"enabled": true,
"key": "ip",
"value": "xx.xx.xx.xx",
"type": "text"
},
{
"enabled": true,
"key": "another server",
"value": "another url",
"type": "text"
}
],
"timestamp": 1517304219458,
"_postman_variable_scope": "environment",
"_postman_exported_at": "2018-01-30T09:23:48.085Z",
"_postman_exported_using": "Postman/5.5.2"
},
"globals": {
"name": "globals-env",
"values": [],
"_postman_variable_scope": "globals"
},
"delayRequest": 500,
"timeoutRequest": 180000,
"insecure": true,
"bail": false,
"suppressExitCode": true,
"reporters": [
"cli"
],
"reporter": {
"cli": {}
},
"folder": "some collection folder"
}
我已经实现了一个小heapUse跟踪程序以及Newman运行代码,如下所示:
var prevStats;
var memPth;
var markHeap, markHeapInit;
function logMemory (path,comment,mark) {
if (! fs.existsSync(path)) {
fs.mkdirSync(path, DIR_MODE);
}
memPth = path;
path = pathUtils.posix.join(path,"memoryLeak.txt");
if (comment) comment = comment.replace(/(.+)/,' - $1');
var memStats = process.memoryUsage();
fs.appendFileSync(path,`\r\n\r\n***Memory Log ${comment}\r\n`);
var diff;
if (prevStats) {
_.forEach (
["heapUsed"],
key => {
if (memStats.hasOwnProperty(key)) {
diff = memStats[key]-prevStats[key];
fs.appendFileSync(path,`\r\nSpike in ${key}: ${diff}`);
if (diff < 0) {
fs.appendFileSync(path,` $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$`);
} else if (diff > 500000) {
fs.appendFileSync(path,` ######################################`);
}
fs.appendFileSync(path,`\r\nHeapUsed: ${memStats[key]}`);
}
}
);
}
if (mark) {
fs.appendFileSync(path,`\r\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%`);
if (markHeap) {
fs.appendFileSync(path,`\r\n\r\n***Marked Spike ${comment} - ${memStats.heapUsed - markHeap} - total: ${memStats.heapUsed}\r\n`);
}
markHeap = memStats.heapUsed;
if (!markHeapInit) {
markHeapInit = markHeap;
} else {
fs.appendFileSync(path,`\r\n***Total Spike ${comment} - ${memStats.heapUsed - markHeapInit} - total: ${memStats.heapUsed}\r\n`);
}
fs.appendFileSync(path,`\r\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%`);
}
prevStats = memStats;
}
function requireNewman() {
//Clearing the require.cache before calling require('newman') gets us a new instance
for (var property in require.cache) {
if (Object.prototype.hasOwnProperty.call(require.cache,property) && property.indexOf('/node_modules/newman') !== -1) {
delete require.cache[property];
}
}
return require('newman');
}
var Newman = requireNewman();
//Neman run code
Newman.run(opts, function (err, summary) {
logMemory(memPth,'After Newman.run');
// done with newman task
runNewmanCb(null, {err: err, summary: summary});
}).on('beforeIteration', function (err, args) {
if (!err && args.cursor.cycles > 1) {
console.log(`Iteration ${args.cursor.iteration}/${args.cursor.cycles}`);
}
logMemory(memPth,'beforeIteration Event');
}).on('exception', function (err, args) {
if (args.error.name !== 'ReferenceError') {
// unknown exception let's log it
}
logMemory(memPth,'exception Event');
}).on('beforeItem', function (err, args) {
logMemory(memPth,'beforeItem Event');
}).on('request', function (err, args) {
var size = args.response && args.response.size();
size = size && (size.header || 0) + (size.body || 0) || 0;
if (err) {
console.error('%s %s [errored]', args.request.method, args.request.url);
} else {
var reqHeaders = _.reduce(args.request.headers.members, function (headerObj, val) {
headerObj[`${val.key}`] = val.value;
return headerObj;
},{});
var requestBodyStr = '';
var bodyLogStr = 'body';
switch (args.request.body.mode) {
case 'raw':
if (args.request.body.raw) {
try {
// try to parse it so it can be displayed beautified by the logger
requestBodyStr = JSON.parse(args.request.body.raw);
} catch (e) {
requestBodyStr = args.request.body.raw;
}
}
break;
case 'formdata':
case 'urlencoded':
case 'binary':
case 'file':
bodyLogStr = args.request.body.mode;
requestBodyStr = args.request.body[args.request.body.mode];
break;
default:
requestBodyStr = args.request.body;
}
var respHeaders = _.reduce(args.response.headers.members, function (headerObj, val) {
headerObj[`${val.key}`] = val.value;
return headerObj;
},{});
var respStream = _.get(args, 'response.stream', '');
var respBodyStr = Buffer.from(respStream).toString();
var jsonRE = /json/i;
if ((respHeaders['Content-Type'] && jsonRE.test(respHeaders['Content-Type']))
|| (reqHeaders['Content-Type'] && jsonRE.test(reqHeaders['Content-Type']))) {
try {
respBodyStr = JSON.parse(respBodyStr);
} catch (e) {
console.log('Unable to parse JSON response', e);
}
}
if (typeof respBodyStr != 'object') {
// likely a string so lets make sure the body gets logged on a newline
respBodyStr = `\n${respBodyStr}`;
}
}
}).on('assertion', function (err, args) {
var passed = !err;
// print each test assertions
}).on('script', function (err, args) {
if (err) {
}
logMemory(memPth,'script Event');
}).on('item', function (err, args) {
logMemory(memPth,'item Event');
}).on('console', function (err, args) {
var lvl = 'info';
switch (args.level) {
case 'log':
lvl = 'info';
break;
default:
lvl = args.level;
}
logMemory(memPth,'console Event');
});
}
十个运行周期的内存峰值可追溯为:
***Memory Log - Before Newman require
***Memory Log - After Newman require
Spike in heapUsed: 41450104 ######################################
HeapUsed: 70518752
***Memory Log - beforeIteration Event
Spike in heapUsed: 12883520 ######################################
HeapUsed: 83402272
***Memory Log - beforeItem Event
Spike in heapUsed: 262592
HeapUsed: 83664864
***Memory Log - script Event
Spike in heapUsed: 1299272 ######################################
HeapUsed: 84964136
***Memory Log - request Event
Spike in heapUsed: 1255296 ######################################
HeapUsed: 86219432
***Memory Log - script Event
Spike in heapUsed: -1266024 $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
HeapUsed: 84953408
***Memory Log - assertion Event
Spike in heapUsed: 110152
HeapUsed: 85063560
***Memory Log - item Event
Spike in heapUsed: 113432
HeapUsed: 85176992
***Memory Log - After Newman.run
Spike in heapUsed: 1070224 ######################################
HeapUsed: 86247216
***Memory Log - Before Newman require
Spike in heapUsed: 5754872 ######################################
HeapUsed: 92002088
***Memory Log - After Newman require
Spike in heapUsed: 138624
HeapUsed: 92140712
***Memory Log - beforeIteration Event
Spike in heapUsed: 14925168 ######################################
HeapUsed: 107065880
***Memory Log - beforeItem Event
Spike in heapUsed: 114584
HeapUsed: 107180464
***Memory Log - script Event
Spike in heapUsed: 1051224 ######################################
HeapUsed: 108231688
***Memory Log - request Event
Spike in heapUsed: 521584 ######################################
HeapUsed: 108753272
***Memory Log - script Event
Spike in heapUsed: 818384 ######################################
HeapUsed: 109571656
***Memory Log - assertion Event
Spike in heapUsed: 116792
HeapUsed: 109688448
***Memory Log - item Event
Spike in heapUsed: 126640
HeapUsed: 109815088
***Memory Log - After Newman.run
Spike in heapUsed: 778640 ######################################
HeapUsed: 110593728
***Memory Log - Before Newman require
Spike in heapUsed: 5657224 ######################################
HeapUsed: 116250952
***Memory Log - After Newman require
Spike in heapUsed: 108216
HeapUsed: 116359168
***Memory Log - beforeIteration Event
Spike in heapUsed: 10163576 ######################################
HeapUsed: 126522744
***Memory Log - beforeItem Event
Spike in heapUsed: 111504
HeapUsed: 126634248
***Memory Log - script Event
Spike in heapUsed: 1147912 ######################################
HeapUsed: 127782160
***Memory Log - request Event
Spike in heapUsed: 492672
HeapUsed: 128274832
***Memory Log - script Event
Spike in heapUsed: 874616 ######################################
HeapUsed: 129149448
***Memory Log - assertion Event
Spike in heapUsed: 107632
HeapUsed: 129257080
***Memory Log - item Event
Spike in heapUsed: 110608
HeapUsed: 129367688
***Memory Log - After Newman.run
Spike in heapUsed: 716344 ######################################
HeapUsed: 130084032
***Memory Log - Before Newman require
Spike in heapUsed: -452992 $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
HeapUsed: 129631040
***Memory Log - After Newman require
Spike in heapUsed: 101280
HeapUsed: 129732320
***Memory Log - beforeIteration Event
Spike in heapUsed: 10040104 ######################################
HeapUsed: 139772424
***Memory Log - beforeItem Event
Spike in heapUsed: 105448
HeapUsed: 139877872
***Memory Log - script Event
Spike in heapUsed: 1048712 ######################################
HeapUsed: 140926584
***Memory Log - request Event
Spike in heapUsed: 504352 ######################################
HeapUsed: 141430936
***Memory Log - script Event
Spike in heapUsed: 786344 ######################################
HeapUsed: 142217280
***Memory Log - assertion Event
Spike in heapUsed: 135240
HeapUsed: 142352520
***Memory Log - item Event
Spike in heapUsed: 98360
HeapUsed: 142450880
***Memory Log - After Newman.run
Spike in heapUsed: 813816 ######################################
HeapUsed: 143264696
***Memory Log - Before Newman require
Spike in heapUsed: -8588720 $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
HeapUsed: 134675976
***Memory Log - After Newman require
Spike in heapUsed: 106616
HeapUsed: 134782592
***Memory Log - beforeIteration Event
Spike in heapUsed: 9580888 ######################################
HeapUsed: 144363480
***Memory Log - beforeItem Event
Spike in heapUsed: 110704
HeapUsed: 144474184
***Memory Log - script Event
Spike in heapUsed: 1029288 ######################################
HeapUsed: 145503472
***Memory Log - request Event
Spike in heapUsed: 469720
HeapUsed: 145973192
***Memory Log - script Event
Spike in heapUsed: 820608 ######################################
HeapUsed: 146793800
***Memory Log - assertion Event
Spike in heapUsed: 119352
HeapUsed: 146913152
***Memory Log - item Event
Spike in heapUsed: 103312
HeapUsed: 147016464
***Memory Log - After Newman.run
Spike in heapUsed: 861520 ######################################
HeapUsed: 147877984
***Memory Log - Before Newman require
Spike in heapUsed: -3996896 $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
HeapUsed: 143881088
***Memory Log - After Newman require
Spike in heapUsed: 103552
HeapUsed: 143984640
***Memory Log - beforeIteration Event
Spike in heapUsed: 5518896 ######################################
HeapUsed: 149503536
***Memory Log - beforeItem Event
Spike in heapUsed: 129160
HeapUsed: 149632696
***Memory Log - script Event
Spike in heapUsed: 1055240 ######################################
HeapUsed: 150687936
***Memory Log - request Event
Spike in heapUsed: 524808 ######################################
HeapUsed: 151212744
***Memory Log - script Event
Spike in heapUsed: 830496 ######################################
HeapUsed: 152043240
***Memory Log - assertion Event
Spike in heapUsed: 124872
HeapUsed: 152168112
***Memory Log - item Event
Spike in heapUsed: 102320
HeapUsed: 152270432
***Memory Log - After Newman.run
Spike in heapUsed: 705120 ######################################
HeapUsed: 152975552
***Memory Log - Before Newman require
Spike in heapUsed: -5252008 $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
HeapUsed: 147723544
***Memory Log - After Newman require
Spike in heapUsed: 97632
HeapUsed: 147821176
***Memory Log - beforeIteration Event
Spike in heapUsed: 563360 ######################################
HeapUsed: 148384536
***Memory Log - beforeItem Event
Spike in heapUsed: 118816
HeapUsed: 148503352
***Memory Log - script Event
Spike in heapUsed: 1044776 ######################################
HeapUsed: 149548128
***Memory Log - request Event
Spike in heapUsed: 537360 ######################################
HeapUsed: 150085488
***Memory Log - script Event
Spike in heapUsed: 884552 ######################################
HeapUsed: 150970040
***Memory Log - assertion Event
Spike in heapUsed: 111296
HeapUsed: 151081336
***Memory Log - item Event
Spike in heapUsed: 101712
HeapUsed: 151183048
***Memory Log - After Newman.run
Spike in heapUsed: 684200 ######################################
HeapUsed: 151867248
***Memory Log - Before Newman require
Spike in heapUsed: 5902880 ######################################
HeapUsed: 157770128
***Memory Log - After Newman require
Spike in heapUsed: 106848
HeapUsed: 157876976
***Memory Log - beforeIteration Event
Spike in heapUsed: 10480696 ######################################
HeapUsed: 168357672
***Memory Log - beforeItem Event
Spike in heapUsed: 112040
HeapUsed: 168469712
***Memory Log - script Event
Spike in heapUsed: 1059784 ######################################
HeapUsed: 169529496
***Memory Log - request Event
Spike in heapUsed: 474552
HeapUsed: 170004048
***Memory Log - script Event
Spike in heapUsed: 780448 ######################################
HeapUsed: 170784496
***Memory Log - assertion Event
Spike in heapUsed: 99568
HeapUsed: 170884064
***Memory Log - item Event
Spike in heapUsed: 109568
HeapUsed: 170993632
***Memory Log - After Newman.run
Spike in heapUsed: 687376 ######################################
HeapUsed: 171681008
***Memory Log - Before Newman require
Spike in heapUsed: -16935080 $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
HeapUsed: 154745928
***Memory Log - After Newman require
Spike in heapUsed: 107600
HeapUsed: 154853528
***Memory Log - beforeIteration Event
Spike in heapUsed: 9497672 ######################################
HeapUsed: 164351200
***Memory Log - beforeItem Event
Spike in heapUsed: 108360
HeapUsed: 164459560
***Memory Log - script Event
Spike in heapUsed: 1048400 ######################################
HeapUsed: 165507960
***Memory Log - request Event
Spike in heapUsed: 539696 ######################################
HeapUsed: 166047656
***Memory Log - script Event
Spike in heapUsed: 803928 ######################################
HeapUsed: 166851584
***Memory Log - assertion Event
Spike in heapUsed: 101560
HeapUsed: 166953144
***Memory Log - item Event
Spike in heapUsed: 101512
HeapUsed: 167054656
***Memory Log - After Newman.run
Spike in heapUsed: 658168 ######################################
HeapUsed: 167712824
***Memory Log - Before Newman require
Spike in heapUsed: -3456624 $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
HeapUsed: 164256200
***Memory Log - After Newman require
Spike in heapUsed: 108560
HeapUsed: 164364760
***Memory Log - beforeIteration Event
Spike in heapUsed: -4130248 $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
HeapUsed: 160234512
***Memory Log - beforeItem Event
Spike in heapUsed: 119920
HeapUsed: 160354432
***Memory Log - script Event
Spike in heapUsed: 1055864 ######################################
HeapUsed: 161410296
***Memory Log - request Event
Spike in heapUsed: 511176 ######################################
HeapUsed: 161921472
***Memory Log - script Event
Spike in heapUsed: 782560 ######################################
HeapUsed: 162704032
***Memory Log - assertion Event
Spike in heapUsed: 101496
HeapUsed: 162805528
***Memory Log - item Event
Spike in heapUsed: 101512
HeapUsed: 162907040
***Memory Log - After Newman.run
Spike in heapUsed: 735088 ######################################
HeapUsed: 163642128
我还实现了一个递归事件发射器gc util,但并没有太大帮助。
这是 Newman 模块运行功能的问题(导致内存泄漏),否则我该如何解决。
在Win 7 OS上, Newman 版本为3.8.3。
最佳答案
这是通过使用child_process
模块实现的,该模块允许为包含newman run code
的模块创建一个新的子进程
newmanCodeModule.js:(包含newman特定代码)
Newman.run(opts, function (err, summary) { ...
流程主模块
Newman 运行模块调用
var processMaster = require('child_process');
//args contain the newman option inputs
processMaster.execSync (`npm run newmanCodeModule.js ${args}`);
内存清理调用(用于在Linux和Win平台上垃圾回收分配的堆-尚未经过Linux测试)
var curHeapUsed;
function killChildRuns (cb) {
var curProcPid = process.pid,
stdout;
var processMaster = require('child_process');
if (/^win/.test(process.platform)) {
stdout = processMaster.execSync('WMIC process where name="node.exe" get ProcessId, CommandLine');
stdout = typeof stdout === 'object' ? stdout.toString() : stdout;
_.forEach (
stdout.split(/[\n\r]+/),
pinfo => {
var match = pinfo.match(/\s+(\d+)\s*$/);
if (match) {
var thisPid = match[1];
if (parseInt(thisPid) !== curProcPid && !pinfo.match(/webServices/i)) {
processMaster.execSync (`taskkill /PID ${thisPid}`);
}
}
}
);
} else {
stdout = processMaster.execSync("ps -eo pid,lstart,cmd | grep node");
stdout = typeof stdout === 'object' ? stdout.toString() : stdout;
_.forEach (
stdout.split(/[\n\r]+/),
pinfo => {
var thisPid = pinfo.match(/([^\s]+\s+){6}/).match(/^([^\s]+)\s+(.+)[^\s]+\s*$/)[0];
if (pinfo.match(/\s+\d+\s*$/) && !(thisPid === curProcPid || pinfo.match(/webServices/i))) {
processMaster.execute (`"kill -9" ${thisPid}`);
}
}
);
}
processMaster = null;
var newHeapUsed = process.memoryUsage().heapUsed;
if (curHeapUsed) {
var heapDiff = newHeapUsed - curHeapUsed;
console.log("Memory Spike after Running iteration suite:");
console.log("*********************************************");
console.log('HeapDiff = '+parseFloat(heapDiff / (1024 * 1024))+ ' MB');
console.log("*********************************************");
} else {
curHeapUsed = newHeapUsed;
}
if (cb) cb();
}