#ruby #memory #object #dump #heap #memory-leaks #process-memory

app reap

一个解析 Ruby 堆快照的工具

7 个版本

0.3.3 2024年2月14日
0.3.2 2023年2月14日
0.3.1 2023年1月6日
0.3.0 2019年8月25日
0.1.0 2019年1月23日

#3#memory-leaks

每月下载量 33

Apache-2.0

37KB
820

reap

通过分析引用图解析 Ruby 堆快照的工具

支持深入分析给定对象保留的内存,并提供可选的图形输出。

何时使用 reap

此工具旨在优化内存使用并调试内存泄漏。如果您有 Ruby 进程的堆快照(以下提供获取快照的提示),则 reap 可帮助您了解快照的内容。

为此,我们根据引用图构建一个 支配树,显示哪些对象正在保留大量内存。在有向图中,如果从给定的根节点到节点 w 的所有路径都经过节点 v,则节点 v “支配” 节点 w。在内存引用的上下文中,这意味着对象 w 仅因对象 v 是活跃的而保持活跃。

限制与比较

reap 目前尚不支持垃圾收集“代”,这也可以用于查找泄漏。

分析 GC 代数的缺点是,为了收集必要的数据,您需要跟踪对象分配,这在生产环境中可能过于昂贵。如果您不介意这个问题,您可能想尝试另一个工具,例如 heapy,而不是 reap 或者在 reap 的基础上。

reap 旨在在未跟踪分配的情况下提供有用的数据。由于是用 Rust 编写的,它还可以在几秒钟内分析相当大(数GB)的堆。

如何使用 reap

运行 --help 以获取完整文档。

基本用法

$ cargo run -q --release -- /tmp/heap.json -f flamegraph.svg -c 3
Object types using the most live memory:
Thread: 2.1 MB (40 objects)
String: 462.6 KB (9235 objects)
Class: 223.7 KB (287 objects)
...: 653.0 KB (5909 objects)

Objects retaining the most live memory:
root: 3.4 MB (15472 objects)
Thread[0x7f83df87dc40]: 1.1 MB (25 objects)
Thread[0x7f83e107cd78]: 1.0 MB (7 objects)
...: 4.6 MB (59857 objects)

Object types retaining the most live memory:
ROOT: 3.4 MB (15472 objects)
Thread: 2.1 MB (70 objects)
ARRAY: 949.3 KB (13053 objects)
...: 3.6 MB (46766 objects)

Objects unreachable from root:
Class: 189.6 KB (617 objects)
String: 81.8 KB (1174 objects)
ARRAY: 38.6 KB (298 objects)
...: 91.5 KB (1422 objects)

Wrote 15471 nodes to flamegraph.svg

深入子树(在这种情况下,较大的 Thread)

$ cargo run -q --release -- /tmp/heap.json -d out.dot -c 3 -r 0x7f83df87dc40
Object types using the most live memory:
Thread: 1.0 MB (1 objects)
Class: 1.6 KB (3 objects)
Hash: 1.3 KB (7 objects)
...: 980 B (14 objects)

Objects retaining the most live memory:
Thread[0x7f83df87dc40]: 1.1 MB (25 objects)
Hash[0x7f83e10452d8][size=5]: 1.2 KB (6 objects)
Object[0x7f83df8d62c8][CLASS]: 992 B (8 objects)
...: 3.0 KB (24 objects)

Object types retaining the most live memory:
Thread: 1.1 MB (25 objects)
Hash: 2.2 KB (12 objects)
Class: 1.9 KB (10 objects)
...: 1.1 KB (16 objects)

Objects reachable from, but not dominated by, 0x7f83df87dc40:
String: 352.3 KB (6604 objects)
Class: 220.6 KB (283 objects)
Regexp: 108.8 KB (139 objects)
...: 465.2 KB (5716 objects)

Wrote 1 nodes & 0 edges to out.dot

安装

确保您已安装 Rust 的 cargo 软件包管理器,然后只需运行 cargo install reap

获取堆快照

如果您已安装 rbtrace,并且需要在要跟踪的进程中使用它,您可以运行

rbtrace -p $PID -e "Thread.new{require 'objspace';f=open('/tmp/heap.json','w');ObjectSpace.dump_all(output: f, full: true);f.close}"

否则,您可以使用 gdb 连接到 Ruby 进程,然后运行

call rb_eval_string_protect("Thread.new{require 'objspace';f=open('/tmp/heap.json','w');ObjectSpace.dump_all(output: f, full: true);f.close}", 0)

依赖项

~8–16MB
~187K SLoC