【发布时间】:2009-05-13 23:14:51
【问题描述】:
我想跟踪各种程序在特定状态下接触了多少内存。例如,假设我有一个图形程序。当它被最小化时,它可能会使用更少的内存,因为它不会重绘窗口,这需要读取图像和字体并执行大量的库函数。这些对象仍然可以在内存中访问,但它们实际上并没有被使用。
top 之类的工具的用途有限,因为它们只说明有多少内存映射到程序的地址空间,以及有多少内存驻留在物理 RAM 中。同样,泄漏检测器只会告诉内存何时不可访问,而不是如果它没有被使用。
是否有现有工具可以以这种方式跟踪积极使用/未使用的内存?如果可能的话,我不仅想跟踪堆上的使用情况,还想跟踪存储程序/库代码的内存中的使用情况。
编辑:我想澄清一下:我想知道程序在某个点之后(即,一旦它达到某个状态)实际读取、写入或执行的内存量。虽然地址空间中的页数和常驻页数是重要的衡量标准,但这不是我想要的。
我现在正在追求三种方法:
- 我编写了一个库,它使用 `mprotect` 清除从 /proc/self/maps 读取的所有内存区域(堆栈及其自己的代码除外)的保护位。它有一个段错误处理程序,可以恢复保护位并增加一个计数器。我用`LD_PRELOAD`加载它,它在收到信号时开始跟踪内存访问。这产生了一些看似虚假地址的真正故障(在故障发生时它们没有存储在任何寄存器或附近的内存中)。
- 我编写了一个 `purge` 程序,它使用 `mmap` 分配和读取内存,直到 `mmap` 返回错误。这有望从目标进程中强制退出所有页面,该进程在“purge”运行时被挂起。然后,当目标进程恢复时,我使用 pidstat 计算页面的数量。这似乎有效,但它是一种非常生硬的工具。它没有提供任何有关被触摸的页面的信息。
- 有人告诉我,valgrind 允许您编写插件,从而在某些事件(例如内存访问)上执行某些操作。到目前为止,这看起来很有希望。
【问题讨论】: