返回博客
调试 内存泄漏 性能优化 macOS

如何用 ProcXray 排查 Mac 内存泄漏

macOS 内存泄漏排查实战指南:使用 ProcXray 的实时内存图表和进程检查功能,快速定位根本原因,彻底解决问题。

内存泄漏是最令人头疼的 bug 之一:应用越来越慢,风扇狂转,却不知道是哪个进程出了问题,更不知道原因何在。本文介绍一套在 macOS 上系统排查内存泄漏的方法,以 ProcXray 为核心工具。

识别症状

在拿起工具之前,先确认你面对的是真正的内存泄漏,而非正常的高占用:

第一步:定位泄漏进程

打开 ProcXray,按内存降序排列。重点关注:

  1. 内存列数值持续攀升的进程
  2. 内存占用与其功能明显不符的进程(例如一个后台守护进程占用 2 GB)

ProcXray 侧边栏的实时内存图表持续更新。锁定可疑进程,观察趋势线——泄漏表现为持续向上的斜线,始终不趋于平稳。

第二步:搞清楚这个进程究竟是什么

点击可疑进程,在**概览(General)**选项卡中查看:

一个吃掉 3 GB 内存的后台 node 进程,在你知道它是 node /Users/me/myapp/server.js 之前毫无意义。

第三步:检查环境变量

切换到环境变量选项卡。Node.js、Python 或 Ruby 应用的内存泄漏有时源于环境配置错误:

将所有环境变量复制为 JSON,仔细检查缓存大小、连接池限制或调试标志。

第四步:检查打开的文件描述符

服务端内存泄漏通常伴随着文件描述符泄漏——进程不断打开文件、套接字或管道,却从不关闭。切换到 ProcXray 的 Connections 选项卡,查看:

一台本应只有 50 个文件描述符的服务器却出现了 10,000 个,是相关资源泄漏的强烈信号。

第五步:检查已加载的动态库

有时泄漏发生在某个原生库中。ProcXray 的 Dylibs 选项卡列出了进程加载的每一个动态库。将其与应用已知依赖进行对比——意外出现的库版本,或本不应存在的库,都可能解释异常行为。

第六步:复现并确认

一旦锁定了嫌疑目标(特定进程 + 代码路径),主动复现泄漏:

  1. 在 ProcXray 中记录该进程当前的内存占用
  2. 触发你怀疑导致泄漏的操作(例如上传文件、执行查询、调用 API)
  3. 在 ProcXray 中观察内存趋势
  4. 等待应用回到空闲状态
  5. 如果内存不回落到基线,说明你已确认泄漏路径

第七步:借助平台工具深入分析

ProcXray 告诉你什么在泄漏以及泄漏发生在哪里。要找到代码层面的原因,需要借助平台专属工具:

Swift / Objective-C 原生应用:

leaks <PID>          # Apple 内置泄漏检测
malloc_history <PID> # 内存分配历史

或使用 Xcode 的 Memory Graph Debugger,以可视化调用树的形式呈现。

Node.js:

node --inspect server.js
# 然后使用 Chrome DevTools 的 Memory 选项卡,或 clinic.js

Python:

from memory_profiler import profile
@profile
def my_function():
    ...

常见泄漏根因

根因信号
无限制缓存内存随请求量线性增长
事件监听器未移除内存随 UI 操作累积
原生库泄漏Dylibs 选项卡中出现版本异常
文件描述符未关闭Connections 选项卡显示大量打开文件
DOM 节点被持久引用即使页面跳转,浏览器进程也不释放内存

小结

  1. 在 ProcXray 中按内存排序,找出持续增长的进程
  2. 通过概览选项卡确认进程身份和启动方式
  3. 检查环境变量,寻找配置错误
  4. 通过 Connections 选项卡排查文件描述符泄漏
  5. 主动复现泄漏路径
  6. 将问题移交 Xcode Memory Debugger、clinic.js 或 memory_profiler 进行代码级分析

立即下载 ProcXray → — 免费使用,macOS Sonoma+。