diff --git a/.kiro/specs/resource-cpu-optimization/tasks.md b/.kiro/specs/resource-cpu-optimization/tasks.md
index 89ffbc3..de4eed5 100644
--- a/.kiro/specs/resource-cpu-optimization/tasks.md
+++ b/.kiro/specs/resource-cpu-optimization/tasks.md
@@ -101,7 +101,7 @@
- **验证:需求 5.2, 5.3, 5.5**
- [~] 7. 实现内存管理模块
- - [~] 7.1 创建 ArgonMemoryManager 类
+ - [x] 7.1 创建 ArgonMemoryManager 类
- 实现构造函数和 ID 跟踪集合
- 实现 setTimeout()、setInterval()、requestAnimationFrame() 包装方法
- 实现对应的清理方法
diff --git a/argon-memory-manager.test.html b/argon-memory-manager.test.html
new file mode 100644
index 0000000..924f529
--- /dev/null
+++ b/argon-memory-manager.test.html
@@ -0,0 +1,564 @@
+
+
+
+
+
+ ArgonMemoryManager 测试
+
+
+
+ 🧠 ArgonMemoryManager 内存管理模块测试
+
+
+
+
1. setTimeout 跟踪测试
+
+
+
+
+
+
+
2. setInterval 跟踪测试
+
+
+
+
+
+
+
3. requestAnimationFrame 跟踪测试
+
+
+
+
+
+
+
4. clearTimeout 测试
+
+
+
+
+
+
+
5. clearAll 统一清理测试
+
+
+
+
+
+
+
+
+
+
7. getStats 统计信息测试
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/argon-memory-manager.test.js b/argon-memory-manager.test.js
new file mode 100644
index 0000000..466bc9f
--- /dev/null
+++ b/argon-memory-manager.test.js
@@ -0,0 +1,216 @@
+/**
+ * ArgonMemoryManager 单元测试
+ * 测试内存管理模块的定时器和动画帧跟踪功能
+ */
+
+// 模拟浏览器环境
+if (typeof window === 'undefined') {
+ global.window = global;
+ global.setTimeout = setTimeout;
+ global.clearTimeout = clearTimeout;
+ global.setInterval = setInterval;
+ global.clearInterval = clearInterval;
+ global.requestAnimationFrame = (callback) => setTimeout(callback, 16);
+ global.cancelAnimationFrame = clearTimeout;
+}
+
+// 加载模块
+require('./argon-performance.js');
+
+const ArgonMemoryManager = window.ArgonMemoryManager;
+
+describe('ArgonMemoryManager', () => {
+ let memoryManager;
+
+ beforeEach(() => {
+ memoryManager = new ArgonMemoryManager();
+ });
+
+ afterEach(() => {
+ // 清理所有定时器
+ memoryManager.clearAll();
+ });
+
+ // Feature: resource-cpu-optimization, Example: setTimeout 跟踪
+ test('should track setTimeout and auto-remove after execution', (done) => {
+ let executed = false;
+
+ const id = memoryManager.setTimeout(() => {
+ executed = true;
+ }, 10);
+
+ // 验证 ID 被跟踪
+ expect(memoryManager.timers.has(id)).toBe(true);
+ expect(memoryManager.getStats().timers).toBe(1);
+
+ // 等待执行完成
+ setTimeout(() => {
+ expect(executed).toBe(true);
+ // 验证执行后自动移除
+ expect(memoryManager.timers.has(id)).toBe(false);
+ expect(memoryManager.getStats().timers).toBe(0);
+ done();
+ }, 50);
+ });
+
+ // Feature: resource-cpu-optimization, Example: setInterval 跟踪
+ test('should track setInterval', (done) => {
+ let count = 0;
+
+ const id = memoryManager.setInterval(() => {
+ count++;
+ }, 10);
+
+ // 验证 ID 被跟踪
+ expect(memoryManager.intervals.has(id)).toBe(true);
+ expect(memoryManager.getStats().intervals).toBe(1);
+
+ // 等待执行几次
+ setTimeout(() => {
+ expect(count).toBeGreaterThan(0);
+ // 手动清除
+ memoryManager.clearInterval(id);
+ expect(memoryManager.intervals.has(id)).toBe(false);
+ expect(memoryManager.getStats().intervals).toBe(0);
+ done();
+ }, 50);
+ });
+
+ // Feature: resource-cpu-optimization, Example: requestAnimationFrame 跟踪
+ test('should track requestAnimationFrame and auto-remove after execution', (done) => {
+ let executed = false;
+
+ const id = memoryManager.requestAnimationFrame(() => {
+ executed = true;
+ });
+
+ // 验证 ID 被跟踪
+ expect(memoryManager.frames.has(id)).toBe(true);
+ expect(memoryManager.getStats().frames).toBe(1);
+
+ // 等待执行完成
+ setTimeout(() => {
+ expect(executed).toBe(true);
+ // 验证执行后自动移除
+ expect(memoryManager.frames.has(id)).toBe(false);
+ expect(memoryManager.getStats().frames).toBe(0);
+ done();
+ }, 50);
+ });
+
+ // Feature: resource-cpu-optimization, Example: clearTimeout 移除跟踪
+ test('should remove timer from tracking when cleared', () => {
+ const id = memoryManager.setTimeout(() => {}, 1000);
+
+ expect(memoryManager.timers.has(id)).toBe(true);
+
+ memoryManager.clearTimeout(id);
+
+ expect(memoryManager.timers.has(id)).toBe(false);
+ });
+
+ // Feature: resource-cpu-optimization, Example: cancelAnimationFrame 移除跟踪
+ test('should remove frame from tracking when cancelled', () => {
+ const id = memoryManager.requestAnimationFrame(() => {});
+
+ expect(memoryManager.frames.has(id)).toBe(true);
+
+ memoryManager.cancelAnimationFrame(id);
+
+ expect(memoryManager.frames.has(id)).toBe(false);
+ });
+
+ // Feature: resource-cpu-optimization, Example: clearAll 清理所有定时器
+ test('should clear all timers, intervals and frames', (done) => {
+ // 创建多个定时器
+ memoryManager.setTimeout(() => {}, 1000);
+ memoryManager.setTimeout(() => {}, 2000);
+ memoryManager.setInterval(() => {}, 100);
+ memoryManager.setInterval(() => {}, 200);
+ memoryManager.requestAnimationFrame(() => {});
+ memoryManager.requestAnimationFrame(() => {});
+
+ const stats = memoryManager.getStats();
+ expect(stats.timers).toBe(2);
+ expect(stats.intervals).toBe(2);
+ expect(stats.frames).toBe(2);
+ expect(stats.total).toBe(6);
+
+ // 清理所有
+ memoryManager.clearAll();
+
+ const statsAfter = memoryManager.getStats();
+ expect(statsAfter.timers).toBe(0);
+ expect(statsAfter.intervals).toBe(0);
+ expect(statsAfter.frames).toBe(0);
+ expect(statsAfter.total).toBe(0);
+
+ done();
+ });
+
+ // Feature: resource-cpu-optimization, Example: 多个定时器跟踪
+ test('should track multiple timers independently', () => {
+ const id1 = memoryManager.setTimeout(() => {}, 1000);
+ const id2 = memoryManager.setTimeout(() => {}, 2000);
+ const id3 = memoryManager.setTimeout(() => {}, 3000);
+
+ expect(memoryManager.getStats().timers).toBe(3);
+
+ memoryManager.clearTimeout(id2);
+
+ expect(memoryManager.getStats().timers).toBe(2);
+ expect(memoryManager.timers.has(id1)).toBe(true);
+ expect(memoryManager.timers.has(id2)).toBe(false);
+ expect(memoryManager.timers.has(id3)).toBe(true);
+ });
+
+ // Feature: resource-cpu-optimization, Example: 传递参数给回调函数
+ test('should pass arguments to setTimeout callback', (done) => {
+ let receivedArgs = null;
+
+ memoryManager.setTimeout((a, b, c) => {
+ receivedArgs = [a, b, c];
+ }, 10, 'arg1', 'arg2', 'arg3');
+
+ setTimeout(() => {
+ expect(receivedArgs).toEqual(['arg1', 'arg2', 'arg3']);
+ done();
+ }, 50);
+ });
+
+ // Feature: resource-cpu-optimization, Example: 传递参数给 setInterval 回调函数
+ test('should pass arguments to setInterval callback', (done) => {
+ let receivedArgs = null;
+
+ const id = memoryManager.setInterval((a, b) => {
+ receivedArgs = [a, b];
+ }, 10, 'test1', 'test2');
+
+ setTimeout(() => {
+ expect(receivedArgs).toEqual(['test1', 'test2']);
+ memoryManager.clearInterval(id);
+ done();
+ }, 50);
+ });
+
+ // Feature: resource-cpu-optimization, Example: getStats 返回正确的统计信息
+ test('should return correct stats', () => {
+ expect(memoryManager.getStats()).toEqual({
+ timers: 0,
+ intervals: 0,
+ frames: 0,
+ total: 0
+ });
+
+ memoryManager.setTimeout(() => {}, 1000);
+ memoryManager.setInterval(() => {}, 1000);
+ memoryManager.requestAnimationFrame(() => {});
+
+ expect(memoryManager.getStats()).toEqual({
+ timers: 1,
+ intervals: 1,
+ frames: 1,
+ total: 3
+ });
+ });
+});
diff --git a/argon-performance.js b/argon-performance.js
index e56dce6..7f81d4e 100644
--- a/argon-performance.js
+++ b/argon-performance.js
@@ -677,6 +677,176 @@ class ArgonRenderOptimizer {
}
}
+// ==========================================================================
+// 内存管理模块
+// ==========================================================================
+
+/**
+ * 内存管理类
+ * 跟踪和管理定时器、间隔定时器和动画帧,确保正确清理避免内存泄漏
+ *
+ * @class ArgonMemoryManager
+ */
+class ArgonMemoryManager {
+ /**
+ * 构造函数
+ * 初始化 ID 跟踪集合
+ */
+ constructor() {
+ this.timers = new Set(); // setTimeout ID 集合
+ this.intervals = new Set(); // setInterval ID 集合
+ this.frames = new Set(); // requestAnimationFrame ID 集合
+ }
+
+ /**
+ * 设置定时器并跟踪
+ * 包装原生 setTimeout,自动跟踪 timer ID
+ *
+ * @param {Function} callback - 回调函数
+ * @param {number} delay - 延迟时间(毫秒)
+ * @param {...*} args - 传递给回调函数的参数
+ * @returns {number} timer ID,可用于手动清除
+ */
+ setTimeout(callback, delay, ...args) {
+ const id = setTimeout(() => {
+ // 执行完成后自动从跟踪集合中移除
+ this.timers.delete(id);
+ callback(...args);
+ }, delay);
+
+ this.timers.add(id);
+ return id;
+ }
+
+ /**
+ * 设置间隔定时器并跟踪
+ * 包装原生 setInterval,自动跟踪 interval ID
+ *
+ * @param {Function} callback - 回调函数
+ * @param {number} interval - 间隔时间(毫秒)
+ * @param {...*} args - 传递给回调函数的参数
+ * @returns {number} interval ID,可用于手动清除
+ */
+ setInterval(callback, interval, ...args) {
+ const id = setInterval(() => {
+ callback(...args);
+ }, interval);
+
+ this.intervals.add(id);
+ return id;
+ }
+
+ /**
+ * 请求动画帧并跟踪
+ * 包装原生 requestAnimationFrame,自动跟踪 frame ID
+ *
+ * @param {Function} callback - 回调函数
+ * @returns {number} frame ID,可用于手动取消
+ */
+ requestAnimationFrame(callback) {
+ const id = requestAnimationFrame((timestamp) => {
+ // 执行完成后自动从跟踪集合中移除
+ this.frames.delete(id);
+ callback(timestamp);
+ });
+
+ this.frames.add(id);
+ return id;
+ }
+
+ /**
+ * 清除定时器
+ * 包装原生 clearTimeout,同时从跟踪集合中移除
+ *
+ * @param {number} id - timer ID
+ * @returns {void}
+ */
+ clearTimeout(id) {
+ clearTimeout(id);
+ this.timers.delete(id);
+ }
+
+ /**
+ * 清除间隔定时器
+ * 包装原生 clearInterval,同时从跟踪集合中移除
+ *
+ * @param {number} id - interval ID
+ * @returns {void}
+ */
+ clearInterval(id) {
+ clearInterval(id);
+ this.intervals.delete(id);
+ }
+
+ /**
+ * 取消动画帧
+ * 包装原生 cancelAnimationFrame,同时从跟踪集合中移除
+ *
+ * @param {number} id - frame ID
+ * @returns {void}
+ */
+ cancelAnimationFrame(id) {
+ cancelAnimationFrame(id);
+ this.frames.delete(id);
+ }
+
+ /**
+ * 清理所有定时器和动画帧
+ * 通常在 PJAX 页面切换或组件销毁时调用
+ * 确保所有待执行的回调都被取消,避免内存泄漏
+ *
+ * @returns {void}
+ */
+ clearAll() {
+ // 清除所有 setTimeout
+ this.timers.forEach(id => {
+ try {
+ clearTimeout(id);
+ } catch (e) {
+ // 静默失败,ID 可能已失效
+ }
+ });
+
+ // 清除所有 setInterval
+ this.intervals.forEach(id => {
+ try {
+ clearInterval(id);
+ } catch (e) {
+ // 静默失败,ID 可能已失效
+ }
+ });
+
+ // 取消所有 requestAnimationFrame
+ this.frames.forEach(id => {
+ try {
+ cancelAnimationFrame(id);
+ } catch (e) {
+ // 静默失败,ID 可能已失效
+ }
+ });
+
+ // 清空所有集合
+ this.timers.clear();
+ this.intervals.clear();
+ this.frames.clear();
+ }
+
+ /**
+ * 获取当前跟踪的定时器数量
+ * 用于调试和性能监控
+ *
+ * @returns {Object} 包含各类定时器数量的对象
+ */
+ getStats() {
+ return {
+ timers: this.timers.size,
+ intervals: this.intervals.size,
+ frames: this.frames.size,
+ total: this.timers.size + this.intervals.size + this.frames.size
+ };
+ }
+}
+
// ==========================================================================
// 模块导出和初始化接口
// ==========================================================================
@@ -702,5 +872,6 @@ if (typeof window !== 'undefined') {
window.ArgonEventManager = ArgonEventManager;
window.ArgonResourceLoader = ArgonResourceLoader;
window.ArgonRenderOptimizer = ArgonRenderOptimizer;
+ window.ArgonMemoryManager = ArgonMemoryManager;
window.initArgonPerformance = initArgonPerformance;
}