已加载共享对象的内存使用情况

Posted

技术标签:

【中文标题】已加载共享对象的内存使用情况【英文标题】:Memory usage of loaded shared objects 【发布时间】:2014-10-28 11:37:51 【问题描述】:

我正在开发一个基于 Linux 的程序,它以共享对象的形式加载许多插件。我想知道的是每个共享对象及其所有数据结构在某个时间点占用了多少内存。有可能这样做吗?如果需要,我可以修改主程序和插件共享对象。

【问题讨论】:

你在做什么样的程序? 这是某种数据分析器。 【参考方案1】:

这是不可能动态的,因为共享对象A.so可能会在运行时动态创建一些对象数据B,这些数据B被共享对象C.so使用然后销毁 因此,您不能说像 B 这样的某些数据“属于”特定的共享对象;您可能(并且应该)对此有约定。见RAII, rule of three, smart pointers, ....

关键是“给定库或共享对象使用了多少内存”这个问题没有意义。内存和地址空间对进程来说是全局的,因此由主程序和所有共享对象、库、插件共享......!

但是,您可以使用proc(5) 来获取有关整个过程的信息。从程序内部,依次读取/proc/self/maps 以获取其地址空间的映射。从程序外部读取 /proc/1234/maps 以获取 pid 1234 的进程。

您可能想使用valgrind。阅读有关memory management、garbage collection、reference counting 的更多信息。您可以查看与resource management 或garbage collection 相关的问题。您可能想要使用 Boehm's conservative garbage collector(如果使用标准 C++ 容器,您需要使用 Boehm gc_allocator,请参阅 this)。关键是某些给定数据的活跃度是程序的 全局 属性,而不是任何特定插件或函数的属性。想想circular references

【讨论】:

啊,好吧,我想这值得一试!看来我应该考虑手工会计什么的。【参考方案2】:

我想知道的是每个共享对象有多少内存,以及所有 它的数据结构,取自某个时间点。是否可以 这样做?

如果程序正在运行并且您有它的 pid,您可以检查它的内存映射。例如:

% pmap 1234
[...]
00007f8702f6a000    148K r-x-- libtinfo.so.5.9
00007f8702f8f000   2044K ----- libtinfo.so.5.9
00007f870318e000     16K r---- libtinfo.so.5.9
[...]

不过,这并不能告诉您有关数据结构等的太多信息。

【讨论】:

请注意 pmap 只是漂亮的打印 /proc/1234/maps @BasileStarynkevitch 我知道,而且大概每个使用它的人都知道扫描它以找出它正在阅读的内容。谢谢!

以上是关于已加载共享对象的内存使用情况的主要内容,如果未能解决你的问题,请参考以下文章

Java内存分析

POSIX 共享内存 - 有多少个内存副本

JVM系列:JVM内存模型

linux查内存-freetop

R中的并行foreach共享内存

快速定位系统内存问题的思路