@electron-memory/monitor 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,510 @@
1
+ import { EventEmitter } from 'events';
2
+
3
+ /**
4
+ * 内存快照数据结构
5
+ * 每次采集产出一个 MemorySnapshot,包含所有进程的内存信息
6
+ */
7
+ /** 单个进程的内存信息 */
8
+ interface ProcessMemoryInfo {
9
+ /** 进程 PID */
10
+ pid: number;
11
+ /** 进程类型:Browser(主进程) / Tab(渲染进程) / GPU / Utility */
12
+ type: 'Browser' | 'Tab' | 'GPU' | 'Utility' | 'Zygote' | string;
13
+ /** 用户可读的进程名称(如窗口标题) */
14
+ name?: string;
15
+ /** 是否是监控面板自身的进程 */
16
+ isMonitorProcess?: boolean;
17
+ /** 来自 app.getAppMetrics() */
18
+ cpu: {
19
+ percentCPUUsage: number;
20
+ idleWakeupsPerSecond: number;
21
+ };
22
+ memory: {
23
+ /** 工作集大小 (KB) - 进程实际使用的物理内存 */
24
+ workingSetSize: number;
25
+ /** 峰值工作集 (KB) */
26
+ peakWorkingSetSize: number;
27
+ /** 私有字节 (KB) - 不与其他进程共享的内存 */
28
+ privateBytes?: number;
29
+ };
30
+ /** 仅渲染进程:关联的 webContents ID */
31
+ webContentsId?: number;
32
+ /** 仅渲染进程:窗口标题 */
33
+ windowTitle?: string;
34
+ }
35
+ /** 主进程 V8 堆统计 */
36
+ interface V8HeapStats {
37
+ /** 已使用堆大小 (bytes) */
38
+ heapUsed: number;
39
+ /** 堆总大小 (bytes) */
40
+ heapTotal: number;
41
+ /** V8 外部内存 (bytes) */
42
+ external: number;
43
+ /** ArrayBuffers 占用 (bytes) */
44
+ arrayBuffers: number;
45
+ /** RSS (bytes) */
46
+ rss: number;
47
+ }
48
+ /** V8 堆详细统计 */
49
+ interface V8HeapDetailStats extends V8HeapStats {
50
+ /** V8 总堆大小 */
51
+ totalHeapSize: number;
52
+ /** V8 已使用堆大小 */
53
+ usedHeapSize: number;
54
+ /** V8 堆大小限制 */
55
+ heapSizeLimit: number;
56
+ /** V8 malloc 已分配内存 */
57
+ mallocedMemory: number;
58
+ /** V8 malloc 峰值 */
59
+ peakMallocedMemory: number;
60
+ /** 分离的上下文数 - 泄漏关键信号 */
61
+ numberOfDetachedContexts: number;
62
+ /** 原生上下文数 */
63
+ numberOfNativeContexts: number;
64
+ /** 堆空间详情 */
65
+ heapSpaces?: V8HeapSpaceInfo[];
66
+ }
67
+ /** V8 堆空间信息 */
68
+ interface V8HeapSpaceInfo {
69
+ name: string;
70
+ size: number;
71
+ usedSize: number;
72
+ availableSize: number;
73
+ physicalSize: number;
74
+ }
75
+ /** 系统内存信息 */
76
+ interface SystemMemoryInfo {
77
+ /** 总物理内存 (bytes) */
78
+ total: number;
79
+ /** 可用物理内存 (bytes) */
80
+ free: number;
81
+ /** 已使用物理内存 (bytes) */
82
+ used: number;
83
+ /** 使用率 (0-100) */
84
+ usagePercent: number;
85
+ }
86
+ /** 渲染进程 V8 详情(需要 preload 注入) */
87
+ interface RendererV8Detail {
88
+ webContentsId: number;
89
+ pid: number;
90
+ heapUsed: number;
91
+ heapTotal: number;
92
+ external: number;
93
+ arrayBuffers: number;
94
+ }
95
+ /** 事件标记 */
96
+ interface EventMark {
97
+ timestamp: number;
98
+ label: string;
99
+ metadata?: Record<string, unknown>;
100
+ }
101
+ /** 完整的内存快照 */
102
+ interface MemorySnapshot {
103
+ /** 快照时间戳 (ms) */
104
+ timestamp: number;
105
+ /** 所属会话 ID */
106
+ sessionId?: string;
107
+ /** 快照序号 */
108
+ seq: number;
109
+ /** 所有进程的内存信息 */
110
+ processes: ProcessMemoryInfo[];
111
+ /** 所有进程的总工作集大小 (KB) */
112
+ totalWorkingSetSize: number;
113
+ /** 主进程 V8 堆统计 */
114
+ mainProcessMemory: V8HeapStats;
115
+ /** 主进程 V8 详细统计 */
116
+ mainProcessV8Detail: V8HeapDetailStats;
117
+ /** 系统内存信息 */
118
+ system: SystemMemoryInfo;
119
+ /** 渲染进程 V8 详情(可选,需要 preload 注入) */
120
+ rendererDetails?: RendererV8Detail[];
121
+ /** 事件标记 */
122
+ marks?: EventMark[];
123
+ }
124
+
125
+ /**
126
+ * 异常检测相关类型
127
+ */
128
+ /** 异常严重级别 */
129
+ type AnomalySeverity = 'info' | 'warning' | 'critical';
130
+ /** 异常类别 */
131
+ type AnomalyCategory = 'memory-leak' | 'spike' | 'threshold' | 'detached-context' | 'trend';
132
+ /** 异常事件 */
133
+ interface AnomalyEvent {
134
+ /** 事件 ID */
135
+ id: string;
136
+ /** 发现时间 */
137
+ timestamp: number;
138
+ /** 严重级别 */
139
+ severity: AnomalySeverity;
140
+ /** 类别 */
141
+ category: AnomalyCategory;
142
+ /** 涉及的进程类型 */
143
+ processType?: string;
144
+ /** 涉及的进程 PID */
145
+ pid?: number;
146
+ /** 标题 */
147
+ title: string;
148
+ /** 详细描述 */
149
+ description: string;
150
+ /** 触发值 */
151
+ value?: number;
152
+ /** 阈值 */
153
+ threshold?: number;
154
+ }
155
+ /** 异常检测规则 */
156
+ interface AnomalyRule {
157
+ /** 规则 ID */
158
+ id: string;
159
+ /** 规则名称 */
160
+ name: string;
161
+ /** 是否启用 */
162
+ enabled: boolean;
163
+ /** 检测函数 */
164
+ detect: (snapshots: MemorySnapshot[], latestSnapshot: MemorySnapshot) => AnomalyEvent | null;
165
+ }
166
+
167
+ /**
168
+ * SDK 配置类型
169
+ */
170
+
171
+ interface MonitorConfig {
172
+ /** 总开关,默认 true */
173
+ enabled: boolean;
174
+ /** 实例化后是否自动开始采集,默认 true */
175
+ autoStart: boolean;
176
+ /** 启动后是否自动打开监控面板,默认 true */
177
+ openDashboardOnStart: boolean;
178
+ /** 采集间隔 (ms),默认 2000 */
179
+ collectInterval: number;
180
+ /** 落盘间隔 (条数),默认 60 */
181
+ persistInterval: number;
182
+ /** 是否采集渲染进程 V8 详情(需要 preload 配合),默认 false */
183
+ enableRendererDetail: boolean;
184
+ /** 是否采集 V8 堆空间详情,默认 true */
185
+ enableV8HeapSpaces: boolean;
186
+ anomaly: {
187
+ /** 是否启用异常检测,默认 true */
188
+ enabled: boolean;
189
+ /** 检测间隔 (ms),默认 30000 */
190
+ checkInterval: number;
191
+ /** 自定义检测规则(追加到内置规则) */
192
+ rules: AnomalyRule[];
193
+ };
194
+ storage: {
195
+ /** 数据存储目录,默认 app.getPath('userData') + '/memory-monitor' */
196
+ directory: string;
197
+ /** 最大保留会话数,默认 50 */
198
+ maxSessions: number;
199
+ /** 单次会话最大时长 (ms),默认 24h */
200
+ maxSessionDuration: number;
201
+ };
202
+ dashboard: {
203
+ /** 窗口宽度,默认 1400 */
204
+ width: number;
205
+ /** 窗口高度,默认 900 */
206
+ height: number;
207
+ /** 是否置顶,默认 false */
208
+ alwaysOnTop: boolean;
209
+ };
210
+ /** 给窗口进程打标签,方便识别 */
211
+ processLabels: Record<string, string>;
212
+ }
213
+
214
+ /**
215
+ * 测试会话相关类型
216
+ */
217
+ interface TestSession {
218
+ /** 会话唯一 ID */
219
+ id: string;
220
+ /** 用户标签,如 "v1.2.0-空载基准" */
221
+ label: string;
222
+ /** 描述 */
223
+ description?: string;
224
+ /** 开始时间 (ms) */
225
+ startTime: number;
226
+ /** 结束时间 (ms) */
227
+ endTime?: number;
228
+ /** 持续时长 (ms) */
229
+ duration?: number;
230
+ /** 状态 */
231
+ status: 'running' | 'completed' | 'aborted';
232
+ /** 快照数量 */
233
+ snapshotCount: number;
234
+ /** 数据文件路径 */
235
+ dataFile: string;
236
+ /** 元数据文件路径 */
237
+ metaFile: string;
238
+ }
239
+ /** 会话索引(存在 sessions.json 中) */
240
+ interface SessionIndex {
241
+ sessions: TestSession[];
242
+ lastUpdated: number;
243
+ }
244
+
245
+ /**
246
+ * 报告与对比相关类型
247
+ */
248
+
249
+ /** 指标统计摘要 */
250
+ interface MetricSummary {
251
+ /** 首次采样值 */
252
+ initial: number;
253
+ /** 最后采样值 */
254
+ final: number;
255
+ min: number;
256
+ max: number;
257
+ avg: number;
258
+ /** 中位数 */
259
+ p50: number;
260
+ p95: number;
261
+ p99: number;
262
+ /** 变化量 final - initial */
263
+ delta: number;
264
+ /** 变化百分比 */
265
+ deltaPercent: number;
266
+ }
267
+ /** 趋势信息 */
268
+ interface TrendInfo {
269
+ /** 线性回归斜率 (bytes/s) */
270
+ slope: number;
271
+ /** 拟合优度 (0~1) */
272
+ r2: number;
273
+ /** 趋势方向 */
274
+ direction: 'stable' | 'growing' | 'shrinking';
275
+ /** 置信度 */
276
+ confidence: 'high' | 'medium' | 'low';
277
+ }
278
+ /** 改进建议 */
279
+ interface Suggestion {
280
+ /** 建议 ID */
281
+ id: string;
282
+ /** 严重级别 */
283
+ severity: 'info' | 'warning' | 'critical';
284
+ /** 类别 */
285
+ category: 'memory-leak' | 'optimization' | 'architecture';
286
+ /** 标题 */
287
+ title: string;
288
+ /** 描述 */
289
+ description: string;
290
+ /** 具体建议步骤 */
291
+ suggestions: string[];
292
+ /** 相关代码示例 */
293
+ relatedCode?: string[];
294
+ }
295
+ /** 会话报告 */
296
+ interface SessionReport {
297
+ sessionId: string;
298
+ label: string;
299
+ description?: string;
300
+ startTime: number;
301
+ endTime: number;
302
+ duration: number;
303
+ environment: {
304
+ electronVersion: string;
305
+ chromeVersion: string;
306
+ nodeVersion: string;
307
+ platform: string;
308
+ arch: string;
309
+ totalSystemMemory: number;
310
+ cpuModel: string;
311
+ cpuCores: number;
312
+ };
313
+ summary: {
314
+ totalProcesses: {
315
+ min: number;
316
+ max: number;
317
+ avg: number;
318
+ };
319
+ totalMemory: MetricSummary;
320
+ byProcessType: {
321
+ browser: MetricSummary;
322
+ renderer: MetricSummary[];
323
+ gpu: MetricSummary | null;
324
+ utility: MetricSummary | null;
325
+ };
326
+ mainV8Heap: {
327
+ heapUsed: MetricSummary;
328
+ heapTotal: MetricSummary;
329
+ external: MetricSummary;
330
+ arrayBuffers: MetricSummary;
331
+ };
332
+ trends: {
333
+ totalMemory: TrendInfo;
334
+ browserMemory: TrendInfo;
335
+ rendererMemory: TrendInfo;
336
+ };
337
+ };
338
+ anomalies: AnomalyEvent[];
339
+ suggestions: Suggestion[];
340
+ dataFile: string;
341
+ }
342
+ /** 指标差异 */
343
+ interface MetricDiff {
344
+ base: number;
345
+ target: number;
346
+ delta: number;
347
+ deltaPercent: number;
348
+ status: 'improved' | 'degraded' | 'unchanged';
349
+ severity?: 'minor' | 'major' | 'critical';
350
+ }
351
+ /** 劣化项 */
352
+ interface Regression {
353
+ metric: string;
354
+ description: string;
355
+ baseValue: number;
356
+ targetValue: number;
357
+ deltaPercent: number;
358
+ severity: 'minor' | 'major' | 'critical';
359
+ suggestion: string;
360
+ }
361
+ /** 改进项 */
362
+ interface Improvement {
363
+ metric: string;
364
+ description: string;
365
+ baseValue: number;
366
+ targetValue: number;
367
+ deltaPercent: number;
368
+ }
369
+ /** 对比报告 */
370
+ interface CompareReport {
371
+ base: {
372
+ sessionId: string;
373
+ label: string;
374
+ };
375
+ target: {
376
+ sessionId: string;
377
+ label: string;
378
+ };
379
+ overall: {
380
+ totalMemory: MetricDiff;
381
+ browserMemory: MetricDiff;
382
+ rendererMemory: MetricDiff;
383
+ gpuMemory: MetricDiff | null;
384
+ };
385
+ v8Heap: {
386
+ heapUsed: MetricDiff;
387
+ heapTotal: MetricDiff;
388
+ external: MetricDiff;
389
+ };
390
+ trendChanges: {
391
+ metric: string;
392
+ baseSlope: number;
393
+ targetSlope: number;
394
+ change: 'improved' | 'degraded' | 'unchanged';
395
+ }[];
396
+ regressions: Regression[];
397
+ improvements: Improvement[];
398
+ verdict: 'pass' | 'warn' | 'fail';
399
+ verdictReason: string;
400
+ }
401
+ /** GC 结果 */
402
+ interface GCResult {
403
+ beforeHeapUsed: number;
404
+ afterHeapUsed: number;
405
+ freed: number;
406
+ freedPercent: number;
407
+ timestamp: number;
408
+ }
409
+
410
+ /**
411
+ * ElectronMemoryMonitor - SDK 主入口
412
+ *
413
+ * 门面类(Facade Pattern),提供简洁的 API
414
+ * 一行代码即可接入:new ElectronMemoryMonitor()
415
+ */
416
+
417
+ declare class ElectronMemoryMonitor extends EventEmitter {
418
+ private config;
419
+ private collector;
420
+ private persister;
421
+ private sessionManager;
422
+ private anomalyDetector;
423
+ private analyzer;
424
+ private dashboard;
425
+ private ipcHandler;
426
+ private started;
427
+ private latestSnapshot;
428
+ constructor(config?: Partial<MonitorConfig>);
429
+ /** 启动监控 */
430
+ start(): Promise<void>;
431
+ /** 停止监控 */
432
+ stop(): Promise<void>;
433
+ /** 销毁实例 */
434
+ destroy(): Promise<void>;
435
+ /** 开始新会话 */
436
+ startSession(label: string, description?: string): string;
437
+ /** 结束当前会话 */
438
+ stopSession(): Promise<SessionReport | null>;
439
+ /** 打开监控面板 */
440
+ openDashboard(): void;
441
+ /** 关闭监控面板 */
442
+ closeDashboard(): void;
443
+ /** 获取当前最新快照 */
444
+ getCurrentSnapshot(): MemorySnapshot | null;
445
+ /** 获取历史会话列表 */
446
+ getSessions(): Promise<TestSession[]>;
447
+ /** 获取指定会话报告 */
448
+ getSessionReport(sessionId: string): Promise<SessionReport | null>;
449
+ /** 获取指定会话的快照数据(支持时间过滤和降采样) */
450
+ getSessionSnapshots(sessionId: string, startTime?: number, endTime?: number, maxPoints?: number): Promise<MemorySnapshot[]>;
451
+ /** 对比两个会话 */
452
+ compareSessions(baseId: string, targetId: string): Promise<CompareReport | null>;
453
+ /** 导出会话数据(供 IPC 调用,弹出保存对话框) */
454
+ exportSession(sessionId: string): Promise<{
455
+ success: boolean;
456
+ filePath?: string;
457
+ error?: string;
458
+ }>;
459
+ /** 导入会话数据(供 IPC 调用,弹出打开对话框) */
460
+ importSession(): Promise<{
461
+ success: boolean;
462
+ session?: TestSession;
463
+ error?: string;
464
+ }>;
465
+ /** 删除指定会话 */
466
+ deleteSession(sessionId: string): Promise<boolean>;
467
+ /** 手动触发 GC */
468
+ triggerGC(): Promise<GCResult>;
469
+ /** 导出堆快照 */
470
+ takeHeapSnapshot(filePath?: string): Promise<string>;
471
+ /** 添加事件标记 */
472
+ mark(label: string, metadata?: Record<string, unknown>): void;
473
+ /** 更新渲染进程 V8 详情 */
474
+ updateRendererDetail(detail: RendererV8Detail): void;
475
+ /** 获取当前配置 */
476
+ getConfig(): MonitorConfig;
477
+ on(event: 'snapshot', handler: (data: MemorySnapshot) => void): this;
478
+ on(event: 'anomaly', handler: (event: AnomalyEvent) => void): this;
479
+ on(event: 'session-end', handler: (report: SessionReport) => void): this;
480
+ private onSnapshot;
481
+ private mergeConfig;
482
+ }
483
+
484
+ /**
485
+ * IPC 通道常量定义
486
+ * 所有通道以 'emm:' 为前缀,避免与业务 IPC 冲突
487
+ */
488
+ declare const IPC_CHANNELS: {
489
+ readonly SNAPSHOT: "emm:snapshot";
490
+ readonly ANOMALY: "emm:anomaly";
491
+ readonly SESSION_START: "emm:session:start";
492
+ readonly SESSION_STOP: "emm:session:stop";
493
+ readonly SESSION_LIST: "emm:session:list";
494
+ readonly SESSION_REPORT: "emm:session:report";
495
+ readonly SESSION_COMPARE: "emm:session:compare";
496
+ readonly SESSION_SNAPSHOTS: "emm:session:snapshots";
497
+ readonly TRIGGER_GC: "emm:gc";
498
+ readonly HEAP_SNAPSHOT: "emm:heap-snapshot";
499
+ readonly MARK: "emm:mark";
500
+ readonly CONFIG_UPDATE: "emm:config:update";
501
+ readonly GET_CONFIG: "emm:config:get";
502
+ readonly GET_SESSIONS: "emm:sessions:get";
503
+ readonly SESSION_EXPORT: "emm:session:export";
504
+ readonly SESSION_IMPORT: "emm:session:import";
505
+ readonly SESSION_DELETE: "emm:session:delete";
506
+ readonly RENDERER_REPORT: "emm:renderer:report";
507
+ readonly RENDERER_REQUEST: "emm:renderer:request";
508
+ };
509
+
510
+ export { type AnomalyCategory, type AnomalyEvent, type AnomalyRule, type AnomalySeverity, type CompareReport, ElectronMemoryMonitor, type EventMark, type GCResult, IPC_CHANNELS, type Improvement, type MemorySnapshot, type MetricDiff, type MetricSummary, type MonitorConfig, type ProcessMemoryInfo, type Regression, type RendererV8Detail, type SessionIndex, type SessionReport, type Suggestion, type SystemMemoryInfo, type TestSession, type TrendInfo, type V8HeapDetailStats, type V8HeapSpaceInfo, type V8HeapStats };