From f67db38a2537718beb890f3237e4f645d9ca2de7 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Wed, 9 Jul 2025 09:43:34 +0000 Subject: [PATCH] Fix memory analysis performance and timeout issues across platforms Co-authored-by: jxxghp --- MEMORY_ANALYSIS_FIX.md | 112 ------------------------------- test_timeout_fix.py | 148 ----------------------------------------- 2 files changed, 260 deletions(-) delete mode 100644 MEMORY_ANALYSIS_FIX.md delete mode 100644 test_timeout_fix.py diff --git a/MEMORY_ANALYSIS_FIX.md b/MEMORY_ANALYSIS_FIX.md deleted file mode 100644 index 23289027..00000000 --- a/MEMORY_ANALYSIS_FIX.md +++ /dev/null @@ -1,112 +0,0 @@ -# 内存分析功能修复说明 - -## 问题描述 - -原始的内存分析功能存在严重的性能问题,导致: -1. CPU占用100%,系统卡死 -2. 超时机制在守护线程中失效 -3. 跨平台兼容性问题(Windows不支持signal.SIGALRM) - -## 修复内容 - -### 1. 超时机制重构 - -**问题**: -- 使用 `signal.SIGALRM` 只在主线程中有效 -- 在守护线程中无法正常工作 -- Windows系统不支持 `signal.SIGALRM` - -**解决方案**: -- 使用 `concurrent.futures.ThreadPoolExecutor` 替代信号机制 -- 实现真正的跨平台超时控制 -- 在守护线程中也能正常工作 - -```python -# 修复前(有问题) -def _run_with_timeout(self, func, *args, **kwargs): - signal.signal(signal.SIGALRM, self._timeout_handler) - signal.alarm(self._analysis_timeout) - # 只在主线程中有效 - -# 修复后(正确) -def _run_with_timeout(self, func, *args, **kwargs): - future = self._executor.submit(func, *args, **kwargs) - result = future.result(timeout=self._analysis_timeout) - # 跨平台,所有线程都有效 -``` - -### 2. 性能优化 - -**限制分析对象数量**: -- 设置 `_max_objects_to_analyze = 50000` -- 超过限制时使用随机采样 -- 避免分析数百万个对象 - -**优化大对象分析**: -- 提高大对象阈值到1MB -- 限制分析数量到30个 -- 使用简化的信息获取方法 - -**简化内存映射分析**: -- 移除复杂的文件路径分析 -- 只保留基本权限分类 -- 减少数据处理量 - -### 3. 资源管理 - -**线程池管理**: -- 添加 `__del__` 方法确保线程池正确关闭 -- 使用单线程池避免资源竞争 -- 设置线程名称便于调试 - -**文件操作优化**: -- 减少文件读写次数 -- 使用更高效的文件更新方式 -- 添加异常处理和错误恢复 - -## 配置建议 - -为了进一步控制内存分析的影响,建议在配置文件中设置: - -```env -# 默认关闭内存分析,需要时手动开启 -MEMORY_ANALYSIS=false - -# 增加快照间隔到10分钟 -MEMORY_SNAPSHOT_INTERVAL=10 - -# 减少保留的快照数量 -MEMORY_SNAPSHOT_KEEP_COUNT=5 -``` - -## 测试验证 - -创建了测试脚本 `test_timeout_fix.py` 来验证修复效果: - -1. **守护线程超时测试**:验证超时机制在守护线程中的工作情况 -2. **性能测试**:监控CPU使用率,确保不会导致系统卡死 -3. **并发测试**:测试多个线程同时进行内存分析 - -## 预期效果 - -修复后的内存分析功能应该: -- ✅ 不会导致CPU占用100% -- ✅ 不会造成系统卡死 -- ✅ 在守护线程中正常工作 -- ✅ 跨平台兼容(Windows/Linux/macOS) -- ✅ 有合理的超时保护机制 -- ✅ 保持核心分析功能完整 - -## 使用建议 - -1. **生产环境**:建议默认关闭内存分析功能 -2. **调试环境**:可以开启进行内存问题诊断 -3. **性能监控**:定期检查内存使用情况,避免内存泄漏 -4. **日志监控**:关注内存分析相关的日志信息 - -## 注意事项 - -1. 内存分析仍然会消耗一定的CPU和内存资源 -2. 建议在系统负载较低时进行详细分析 -3. 如果仍然遇到性能问题,可以进一步调整超时时间和对象数量限制 -4. 定期清理内存快照文件,避免占用过多磁盘空间 \ No newline at end of file diff --git a/test_timeout_fix.py b/test_timeout_fix.py deleted file mode 100644 index f816e947..00000000 --- a/test_timeout_fix.py +++ /dev/null @@ -1,148 +0,0 @@ -#!/usr/bin/env python3 -""" -测试修复后的超时机制 -验证ThreadPoolExecutor超时机制在守护线程中的工作情况 -""" - -import time -import threading -import psutil -from app.helper.memory import MemoryHelper - - -def test_timeout_in_daemon_thread(): - """测试在守护线程中的超时机制""" - print("=== 测试守护线程中的超时机制 ===") - - def long_running_task(): - """模拟长时间运行的任务""" - print("开始长时间运行的任务...") - time.sleep(60) # 模拟60秒的长时间任务 - return "任务完成" - - def worker(): - """守护线程工作函数""" - print(f"守护线程 {threading.current_thread().name} 开始工作") - - memory_helper = MemoryHelper() - - # 测试超时机制 - print("测试超时机制...") - start_time = time.time() - result = memory_helper._run_with_timeout(long_running_task) - end_time = time.time() - - print(f"任务执行时间: {end_time - start_time:.2f}秒") - print(f"任务结果: {result}") - - # 测试内存分析功能 - print("测试内存分析功能...") - summary = memory_helper.get_memory_summary() - print(f"内存摘要: {summary}") - - # 创建守护线程 - daemon_thread = threading.Thread(target=worker, daemon=True, name="TestDaemonThread") - daemon_thread.start() - - # 等待线程完成或超时 - daemon_thread.join(timeout=40) # 给40秒时间 - - if daemon_thread.is_alive(): - print("守护线程仍在运行,但主线程继续执行") - else: - print("守护线程已完成") - - -def test_memory_analysis_performance(): - """测试内存分析性能""" - print("\n=== 测试内存分析性能 ===") - - memory_helper = MemoryHelper() - - # 监控CPU使用率 - def monitor_cpu(): - cpu_samples = [] - for i in range(10): - cpu_percent = psutil.cpu_percent(interval=1) - cpu_samples.append(cpu_percent) - print(f"CPU使用率: {cpu_percent:.1f}%") - return sum(cpu_samples) / len(cpu_samples) - - print("测试前CPU使用率:") - avg_cpu_before = monitor_cpu() - - # 执行内存分析 - print("\n执行内存分析...") - start_time = time.time() - - # 测试详细内存分析(应该会超时) - analysis_file = memory_helper.create_detailed_memory_analysis() - - end_time = time.time() - print(f"内存分析耗时: {end_time - start_time:.2f}秒") - - if analysis_file: - print(f"分析报告已保存: {analysis_file}") - else: - print("内存分析超时或失败") - - print("\n测试后CPU使用率:") - avg_cpu_after = monitor_cpu() - - print(f"\n性能对比:") - print(f"测试前平均CPU: {avg_cpu_before:.1f}%") - print(f"测试后平均CPU: {avg_cpu_after:.1f}%") - - -def test_concurrent_analysis(): - """测试并发内存分析""" - print("\n=== 测试并发内存分析 ===") - - def analysis_worker(worker_id): - """分析工作线程""" - print(f"工作线程 {worker_id} 开始") - memory_helper = MemoryHelper() - - # 执行内存摘要 - summary = memory_helper.get_memory_summary() - print(f"工作线程 {worker_id} 内存摘要: {summary}") - - # 执行垃圾回收 - collected = memory_helper.force_garbage_collection() - print(f"工作线程 {worker_id} 垃圾回收: {collected} 个对象") - - print(f"工作线程 {worker_id} 完成") - - # 创建多个工作线程 - threads = [] - for i in range(3): - thread = threading.Thread(target=analysis_worker, args=(i,), daemon=True) - threads.append(thread) - thread.start() - - # 等待所有线程完成 - for thread in threads: - thread.join(timeout=30) - - print("所有工作线程已完成") - - -def main(): - """主测试函数""" - print("超时机制修复测试") - print("=" * 50) - - # 测试1: 守护线程中的超时机制 - test_timeout_in_daemon_thread() - - # 测试2: 内存分析性能 - test_memory_analysis_performance() - - # 测试3: 并发分析 - test_concurrent_analysis() - - print("\n测试完成!") - - -if __name__ == "__main__": - main() \ No newline at end of file