【问题标题】:C++ Program immediately using 2 GB of RAM: how to find culprit?立即使用 2 GB RAM 的 C++ 程序:如何找到罪魁祸首?
【发布时间】:2013-01-30 16:03:27
【问题描述】:

我有一个程序,当在初始化时被查询时,它会立即使用 > 2 GB 的 RAM。基本上代码是这样的:

#include <blah>

int main() {
    cout << get_mem_usage() << endl;
    //Lots of things happen, but no significant memory usage
    return 0;
}

输出: [2013-02-15 18:38:05.865283] 2147.71 Mb

然而,我正在链接到许多不同的共享对象文件:我检查了 ldd,我正在链接到 58 个库,总 .so 大小为 66 MB。

我很确定 get_mem_usage 程序正在返回正确的值:这些值与 top 和 massif 输出一致。

我还应该提到,我正在链接用于高能物理分析的 ROOT 框架。

我使用的是 Linux x86_64,get_mem_usage() 函数是自制的。

如果可能的话,我想减少程序的内存使用量。

【问题讨论】:

  • 什么是get_mem_usage
  • 问题是什么?想知道哪些库消耗多少?
  • 您是否查看过您的 .map 文件以了解静态 RAM 初始化的位置和数量?小心,您也可以跟踪库中的动态分配。
  • @Michael Dorgan:.map 文件是否仅适用于 Windows?
  • get_mem_usage 是一个函数吗?如果是这样,您显示的(伪)代码将不会调用该函数 - 它会打印其地址。

标签: c++ memory-management ram


【解决方案1】:

我的第一个猜测:您正在链接的某些库中的静态初始化。

main() 的第一行插入一个长时间的停顿,并查看/proc// 以查看内存分配的位置。例如:

  • /proc/12345/task/12345/maps
  • /proc/12345/task/12345/smaps

【讨论】:

【解决方案2】:

我在get_mem_usage() 上找不到任何文档。

它报告了什么样的内存使用情况?

确定虚拟内存系统中的内存使用情况是一个相当大的挑战。

实际使用的内存量是您的resident set size。这基本上是您正在使用的任何物理内存。尽管使用共享库(例如 libc),但内存消耗也(部分)与其他应用程序共享。

然后有一个虚拟集大小 - 任何映射的虚拟内存、任何匿名映射、任何其他映射文件的总和。其中大部分不会真正得到物理内存的支持(即不是常驻内存),并且可能会在其他程序之间共享。

pmap -x &lt;pid&gt; 会给你一张整洁的桌子,包括常驻/肮脏的部分。

总体而言,值得研究是什么“使用”了所有这些内存,但这可能根本不是什么大问题。如果您在 32 位系统上运行,那么以后可能会变得有点紧张(因为您的虚拟地址空间是有限的)。

【讨论】:

  • 对不起 - get_mem_usage() 是本土的。它只查看 /proc//statm 的输出。就我而言,这是一个配置不当的 fortran 库,它会立即初始化一个巨大的数组,并且使用的大量内存无法由其他进程共享(据我了解)。
【解决方案3】:

另一种可能性:如果您的应用程序之间有共享内存,那么该共享内存将计入访问共享内存段的每个应用程序,即使它只分配一次。因此,如果在某处分配了 2gb 共享内存段,并且 20 个不同的应用程序使用该共享内存,那么所有 20 个应用程序似乎都在使用 2+gb 的内存,看起来好像已分配了 40+gb 的内存.

【讨论】:

  • 当然是静态初始化之上的乘数
【解决方案4】:

在这种情况下,它原来是一个分配 1.9 G 内存的库(我没有直接使用)。我通过查看 /proc/12345/smaps 找到了它

2aaab2197000-2aab2ba86000 rw-p 2aaab2197000 00:00 0 
Size:           1991612 kB

在 /proc/12345/maps 中查找我找到的地址

2aaab2174000-2aaab2197000 rw-p 0016c000 4f9:2c566 59607963               /mnt/lustre/epp_scratch/atlas/sm442/Irvex/lhapdf-5.8.8/lib/.libs/libLHAPDF.so.0.0.0

这是一个执行大量静态初始化的fortran库。

【讨论】:

  • 如果这是正确的答案,请选择它。选择自己的答案不会获得任何分数,但它会从无休止的未回答问题列表中删除该问题。
猜你喜欢
  • 2015-04-09
  • 1970-01-01
  • 2015-04-04
  • 1970-01-01
  • 2022-08-02
  • 1970-01-01
  • 2012-05-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多