当前位置: 首页 > news >正文

py-spy:不改动代码就能分析 Python 性能

文章目录

  • py-spy:不改动代码就能分析 Python 性能
    • 三个命令覆盖日常需求
    • 跨平台和多版本支持
    • 工作原理
    • 权限相关
    • 什么时候用它

py-spy:不改动代码就能分析 Python 性能

Python 程序跑得慢,定位瓶颈是个常见需求。常规做法是在代码里插入分析逻辑,或者重启程序挂上分析器。py-spy 提供了一条不同的路径:直接读取运行中的 Python 进程,不用改一行代码,也不用重启服务。

这个项目用 Rust 写成,核心目标是低侵入。它不和被分析的 Python 进程跑在同一个空间里,而是通过操作系统提供的内存读取接口,直接采样目标进程的调用栈。这意味着你可以在生产环境直接用它,对正在服务的程序影响极小。

三个命令覆盖日常需求

py-spy 的命令行接口很简洁,只有三个子命令。

record用于生成性能报告。指定目标进程的 PID,或者直接跟 Python 命令,它会持续采样并输出火焰图 SVG 文件。输出格式也支持 speedscope 和原始数据,方便用其他工具二次分析。

top提供一个实时视图,类似系统自带的 top 命令,但显示的是 Python 层面的函数耗时排名。适合快速定位当前最热的代码路径。

dump则是一次性输出所有线程的调用栈。程序卡住的时候,用这个命令看一眼各线程停在哪儿,往往就能定位问题所在。

跨平台和多版本支持

py-spy 支持 Linux、macOS、Windows 和 FreeBSD。Python 版本覆盖 2.3 到 2.7,以及 3.3 到 3.14。这个范围相当宽, legacy 项目和新项目都能用。

安装方式也灵活。PyPI 上有预编译的 wheel,一条 pip 命令就能装好。macOS 用户可以用 Homebrew,Arch Linux 用户可以从 AUR 安装。如果你是 Rust 开发者,也可以直接 cargo install 从源码编译。

工作原理

py-spy 直接读取目标进程的内存来还原 Python 调用栈。在 Linux 上通过 process_vm_readv,macOS 上用 vm_read,Windows 上用 ReadProcessMemory。

具体做法是:先找到 PyInterpreterState 的位置,拿到所有线程列表,再逐个遍历 PyFrameObject 来还原调用链。由于 CPython 的内存布局随版本变化,项目用 bindgen 为每个支持的版本生成对应的 Rust 结构体,确保能正确解析。

ASLR(地址空间布局随机化)会带来一些麻烦。如果 Python 解释器带有符号表,可以直接从 interp_head 或 _PyRuntime 变量定位解释器地址。但很多发行版会剥离符号,这时 py-spy 会扫描 BSS 段,寻找符合 PyInterpreterState 特征的内存地址。

权限相关

读取其他进程的内存通常需要特定权限。macOS 上必须 root 运行。Linux 的默认配置更细:如果由 py-spy 启动目标进程,一般不需要 root;但附加到已有进程通常需要 sudo。这个限制可以通过调整 ptrace_scope 参数来放宽。

Docker 和 Kubernetes 环境里也常见权限问题,需要给容器添加 SYS_PTRACE 能力。文档里对这些场景都有具体说明。

什么时候用它

如果你需要分析一个已经在跑的 Python 服务,又不想重启或修改代码,py-spy 是个直接的选择。它的开销足够低,对线上服务的影响在可接受范围内。

火焰图输出对理解程序热点很直观。GIL 检测功能可以帮你判断多线程程序里哪些线程在争用全局锁。子进程分析功能则对用了 multiprocessing 或 gunicorn 的架构有用。

这个项目目前有 15,236 个 Star,解决的是一个具体的工程问题:在生产环境安全地分析 Python 性能。

,236 个 Star,解决的是一个具体的工程问题:在生产环境安全地分析 Python 性能。

http://www.jsqmd.com/news/971670/

相关文章:

  • KLOGG日志分析工具:5个核心功能解决海量日志处理难题
  • 你 课以的
  • Windows 10系统终极清理指南:3种方法彻底移除预装垃圾软件,提升性能与隐私保护
  • 别再为认证头疼了!微信小程序+ModelArts实战:IAM Token获取的3个关键细节与Scope选择
  • 北京GEO优化哪家靠谱?2026主流服务商横向对比与选型指南
  • 别再乱用data和xdata了!51单片机内存分配保姆级避坑指南(附Keil C51配置)
  • 殊途同归:大成智慧学、地理科学和融智学
  • 微信小程序调用华为云ModelArts模型保姆级教程(从IAM Token到API调用)
  • 告别环境噩梦:用Docker Compose一键部署gem5 GCN3 GPU模拟器与VSCode开发调试环境
  • AD7606与TI F28335 DSP联调避坑全记录:从原理图焊接到CCS代码调试的完整指南
  • Arduino 工程迁移到 PlatformIO 步骤
  • 从“只会敲代码”到“能做项目”:计算机专业的能力跃迁之路
  • 丰田车机维修不求人:手把手教你用示波器诊断AVC-LAN音频总线故障
  • 自动化构建-make/Makefile
  • 保姆级教程:用OpenCV+Python一步步搞定双目相机标定与三维重建
  • Proteus仿真中PCF8574驱动LCD1602的5个常见坑点及解决方法
  • 终极文件编码检测工具:EncodingChecker让你的乱码问题5分钟解决
  • 别再手动整理BOM了!用Excel自定义Altium Designer料单模板,效率翻倍(附模板文件)
  • 使用 Webwright 在 CSDN 自动发文:Python 浏览器自动化实践
  • Almanac:基于行动层面的智能体协作心智模型标注数据集与行为预测基准
  • 量子计算基础:两层级门的原理与应用
  • llama-cpp-python:llama.cpp 的 Python 绑定库
  • C/C++ 基础笔记(九)
  • 杨逢昌——管理咨询与6S实战专家
  • 在AutoDL云服务器上无图形界面安装Matlab 2018b:一份给深度学习研究者的保姆级教程
  • Agent 的规划、执行、反思闭环怎么实现?别把 Reflect 写成小作文
  • 别再让数据裸奔了!手把手教你为Hadoop HDFS 3.x配置透明加密(附KMS避坑指南)
  • STM32MP157双核开发实战:用STM32CubeIDE搞定M4核固件,并与A7核Linux通信(OpenAMP示例解析)
  • 中央空调-水系统 全面解析
  • uniapp小兔新儿day2