-
Notifications
You must be signed in to change notification settings - Fork 283
Expand file tree
/
Copy pathtest_memory_leak.js
More file actions
179 lines (148 loc) · 5.4 KB
/
test_memory_leak.js
File metadata and controls
179 lines (148 loc) · 5.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
#!/usr/bin/env node
/**
* 内存泄露测试脚本
* 用于测试 mediaProxy 接口的内存使用情况
*/
import http from 'http';
import { performance } from 'perf_hooks';
const TEST_URL = 'http://localhost:5757/mediaProxy';
const TEST_MEDIA_URL = 'https://httpbin.org/bytes/1024'; // 测试用的1KB数据
const CONCURRENT_REQUESTS = 10;
const TEST_DURATION = 60000; // 60秒测试
const MEMORY_CHECK_INTERVAL = 5000; // 每5秒检查一次内存
let requestCount = 0;
let errorCount = 0;
let activeRequests = 0;
// 内存监控
function logMemoryUsage() {
const usage = process.memoryUsage();
console.log(`[${new Date().toISOString()}] Memory Usage:`, {
rss: `${Math.round(usage.rss / 1024 / 1024)}MB`,
heapUsed: `${Math.round(usage.heapUsed / 1024 / 1024)}MB`,
heapTotal: `${Math.round(usage.heapTotal / 1024 / 1024)}MB`,
external: `${Math.round(usage.external / 1024 / 1024)}MB`,
activeRequests: activeRequests,
totalRequests: requestCount,
errors: errorCount
});
}
// 发送测试请求
function sendTestRequest() {
return new Promise((resolve) => {
activeRequests++;
const startTime = performance.now();
const queryParams = new URLSearchParams({
url: TEST_MEDIA_URL,
thread: '2',
size: '64K',
randUa: '0'
}).toString();
const options = {
hostname: 'localhost',
port: 5757,
path: `/mediaProxy?${queryParams}`,
method: 'GET',
headers: {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
},
timeout: 30000
};
const req = http.request(options, (res) => {
let dataReceived = 0;
res.on('data', (chunk) => {
dataReceived += chunk.length;
});
res.on('end', () => {
const duration = performance.now() - startTime;
requestCount++;
activeRequests--;
if (res.statusCode === 200 || res.statusCode === 206) {
console.log(`✓ Request ${requestCount} completed in ${Math.round(duration)}ms, received ${dataReceived} bytes (status: ${res.statusCode})`);
} else {
console.log(`✗ Request ${requestCount} failed with status ${res.statusCode}`);
errorCount++;
}
resolve();
});
res.on('error', (error) => {
console.error(`✗ Response error for request ${requestCount}:`, error.message);
errorCount++;
activeRequests--;
resolve();
});
});
req.on('error', (error) => {
console.error(`✗ Request error:`, error.message);
errorCount++;
activeRequests--;
resolve();
});
req.on('timeout', () => {
console.error(`✗ Request timeout`);
errorCount++;
activeRequests--;
req.destroy();
resolve();
});
req.end();
});
}
// 并发测试
async function runConcurrentTest() {
console.log(`Starting memory leak test...`);
console.log(`Test URL: ${TEST_URL}`);
console.log(`Media URL: ${TEST_MEDIA_URL}`);
console.log(`Concurrent requests: ${CONCURRENT_REQUESTS}`);
console.log(`Test duration: ${TEST_DURATION / 1000} seconds`);
console.log('---');
// 开始内存监控
const memoryInterval = setInterval(logMemoryUsage, MEMORY_CHECK_INTERVAL);
logMemoryUsage(); // 初始内存状态
const startTime = Date.now();
// 持续发送并发请求
while (Date.now() - startTime < TEST_DURATION) {
const promises = [];
for (let i = 0; i < CONCURRENT_REQUESTS; i++) {
promises.push(sendTestRequest());
}
await Promise.all(promises);
// 短暂延迟避免过于频繁的请求
await new Promise(resolve => setTimeout(resolve, 100));
}
clearInterval(memoryInterval);
// 等待所有请求完成
while (activeRequests > 0) {
console.log(`Waiting for ${activeRequests} active requests to complete...`);
await new Promise(resolve => setTimeout(resolve, 1000));
}
console.log('---');
console.log('Test completed!');
logMemoryUsage(); // 最终内存状态
console.log(`Total requests: ${requestCount}`);
console.log(`Errors: ${errorCount}`);
console.log(`Success rate: ${((requestCount - errorCount) / requestCount * 100).toFixed(2)}%`);
// 强制垃圾回收
if (global.gc) {
console.log('Running garbage collection...');
global.gc();
setTimeout(() => {
console.log('Memory after GC:');
logMemoryUsage();
process.exit(0);
}, 2000);
} else {
console.log('Garbage collection not available. Run with --expose-gc flag for better memory analysis.');
process.exit(0);
}
}
// 处理程序退出
process.on('SIGINT', () => {
console.log('\nTest interrupted by user');
process.exit(0);
});
process.on('uncaughtException', (error) => {
console.error('Uncaught exception:', error);
process.exit(1);
});
// 启动测试
runConcurrentTest().catch(console.error);