From 2b131de7022f890c8e3fc098eabd2f75122cb8d0 Mon Sep 17 00:00:00 2001 From: JOJO <1498581755@qq.com> Date: Fri, 17 Jul 2026 12:16:16 +0800 Subject: [PATCH] =?UTF-8?q?perf(debug):=20=E5=86=85=E5=AD=98=E7=9B=91?= =?UTF-8?q?=E6=8E=A7=E5=A2=9E=E5=BC=BA=E4=B8=BA=20100ms=20=E9=87=87?= =?UTF-8?q?=E6=A0=B7=20+=20=E5=A4=9A=E7=BB=B4=E5=BA=A6=E6=8C=87=E6=A0=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 采样间隔从 1s 降到 100ms,spike 阈值降到 50MB - 增加 uss/shared/private/data/dirty/compressed 等指标 - 更贴近 macOS 活动监视器'内存'列的统计口径 --- modules/memory_debug.py | 63 +++++++++++++++++++++++++++++------------ 1 file changed, 45 insertions(+), 18 deletions(-) diff --git a/modules/memory_debug.py b/modules/memory_debug.py index 20d8d1c..c5d7d1e 100644 --- a/modules/memory_debug.py +++ b/modules/memory_debug.py @@ -93,11 +93,40 @@ def _current_vms_mb() -> Optional[float]: return None -def get_memory_info() -> Dict[str, Optional[float]]: - return { +def _get_detailed_memory_info() -> Dict[str, Optional[float]]: + """获取更详细的内存指标,更接近 macOS 活动监视器。""" + result: Dict[str, Optional[float]] = { "rss_mb": _current_rss_mb(), "vms_mb": _current_vms_mb(), + "uss_mb": None, + "shared_mb": None, + "private_mb": None, + "data_mb": None, + "dirty_mb": None, + "compressed_mb": None, } + try: + import psutil + proc = psutil.Process() + info = proc.memory_info() + # uss 只在 memory_full_info() 中提供 + try: + full = proc.memory_full_info() + result["uss_mb"] = getattr(full, "uss", None) / (1024 * 1024) if getattr(full, "uss", None) else None + result["compressed_mb"] = getattr(full, "compressed", None) / (1024 * 1024) if getattr(full, "compressed", None) else None + except Exception: + pass + result["shared_mb"] = getattr(info, "shared", None) / (1024 * 1024) if getattr(info, "shared", None) else None + result["private_mb"] = getattr(info, "private", None) / (1024 * 1024) if getattr(info, "private", None) else None + result["data_mb"] = getattr(info, "data", None) / (1024 * 1024) if getattr(info, "data", None) else None + result["dirty_mb"] = getattr(info, "dirty", None) / (1024 * 1024) if getattr(info, "dirty", None) else None + except Exception: + pass + return result + + +def get_memory_info() -> Dict[str, Optional[float]]: + return _get_detailed_memory_info() def _estimate_text_size(text: Any) -> int: @@ -247,20 +276,21 @@ class TopAllocator: def _periodic_sampling( - interval_seconds: float = 1.0, - spike_threshold_mb: float = 100.0, - max_records: int = 3, + interval_seconds: float = 0.1, + spike_threshold_mb: float = 50.0, + max_records: int = 10, ) -> None: - """后台线程:每秒采样一次内存,发现快速增长或峰值时记录。""" + """后台线程:每 100ms 采样一次内存,发现快速增长或峰值时记录。""" global _last_sample_rss_mb, _peak_rss_mb records_since_spike = 0 + last_regular_log = 0.0 while ENABLED: try: info = get_memory_info() rss = info.get("rss_mb") - vms = info.get("vms_mb") if rss is not None: spike = False + delta = None if _last_sample_rss_mb is not None: delta = rss - _last_sample_rss_mb if delta >= spike_threshold_mb: @@ -271,19 +301,16 @@ def _periodic_sampling( records_since_spike -= 1 log_memory_event( "memory_periodic_spike", - rss_mb=rss, - vms_mb=vms, - peak_rss_mb=_peak_rss_mb, - delta_from_last_mb=(delta if spike else None), + **info, + delta_from_last_mb=delta, ) else: - # 每 5 秒记录一次常规采样,避免日志过多 - if int(time.time()) % 5 == 0: + now = time.time() + if now - last_regular_log >= 2.0: + last_regular_log = now log_memory_event( "memory_periodic_sample", - rss_mb=rss, - vms_mb=vms, - peak_rss_mb=_peak_rss_mb, + **info, ) except Exception: pass @@ -291,8 +318,8 @@ def _periodic_sampling( def start_periodic_sampling( - interval_seconds: float = 1.0, - spike_threshold_mb: float = 100.0, + interval_seconds: float = 0.1, + spike_threshold_mb: float = 50.0, ) -> None: """启动后台内存采样线程。幂等:重复调用不会启动多个线程。""" global _sample_thread