Gnome资源监视器报告的C ++程序中的内存使用情况:混乱

时间:2014-10-16 15:54:17

标签: c++ linux memory-management gnome

我正在查看我的应用程序消耗的内存,以确保我没有分配太多,并且对于Gnome资源监视器向我显示的内容感到困惑。我已经使用以下代码片段在两个相同的应用程序中分配内存;它们只包含此代码和scanf()调用以暂停执行,同时我获取内存使用情况:

malloc(1024 * 1024 * 100);

char* p = new char[1204*1024*100];

下图显示了我的应用在每行之前和之后的内存使用情况:

Memory use

现在,我已经阅读了很多(但显然还不够)关于内存使用情况(包括this SO问题),并且无法区分可写内存和虚拟内存。根据相关问题,

  

"可写内存是进程具有的地址空间量   分配了写权限"

  

"虚拟内存是应用程序具有的地址空间   分配"

1)如果我自己分配了内存,肯定它有写权限吗?

2)链接的问题也说明(关于malloc)

  

" ...它实际上没有分配任何内存。 (见最后的咆哮   有关详细信息,请参阅malloc(3)页面。)"

我没有看到任何" rant",我的图片显示虚拟内存增加了!有人可以解释一下吗?

3)如果我纯粹使用以下代码:

char* p = new char[100];

...资源监视器显示内存和可写内存都增加了8KB - 与我分配一个完整的1兆字节时相同! - 虚拟内存增加0.1。这里发生了什么?

4)我应该在资源监视器中查看哪一列,以查看我的应用程序使用了多少内存?

非常感谢您提前参与,如果不清楚或遗漏任何可能导致我自己找到答案的任何事情,我很抱歉。

2 个答案:

答案 0 :(得分:2)

在Linux上了解正在运行的process的内存使用情况的更精确方法是使用proc(5)文件系统。

因此,如果您的流程pid是1234,请尝试

cat /proc/1234/maps

请注意,流程的address space位于virtual memory。该地址空间可以由mmap(2)和其他syscalls(2)更改。出于多种效率原因,malloc(3)free可以避免过多地使用这些系统调用,并且更愿意重复使用以前的free - d内存区域。因此,当你的程序是free - (或者,在C ++中,delete - )一些内存块时,该块通常被标记为可重用但不会被释放回内核(例如,通过munmap)。同样,如果malloc只有100个字节,则允许libc {使用mmap请求整整兆字节(下次您呼叫malloc例如200字节时,它将使用该磁带的一部分)

另请参阅http://linuxatemyram.com/Advanced Linux Programming(和this question关于内存过量使用)

答案 1 :(得分:1)

Gnome资源监视器(实际上是绝大多数资源报告工具)报告的内存类别不仅仅是单独的内存类别 - 它们之间存在重叠,因为它们报告了内存的不同特征。其中一些不同的特征包括:

  • 虚拟与物理 - 现代操作系统上进程地址空间中的所有内存都是虚拟的;虚拟地址空间通过CPU的硬件功能映射到实际物理内存;如何完成映射本身就是一个复杂的主题,不同架构之间存在很多差异
  • 内存访问权限 - 内存可以是可读,可写或可执行的,或三者的任意组合(理论上 - 某些组合确实没有意义,因此硬件和/或软件实际上可能不允许这样做,但重点是这些权限是分开处理的)
  • 驻留与非驻留 - 使用虚拟内存系统,由于各种原因,进程的大部分地址空间实际上可能实际上并未映射到实际物理内存 - 它可能尚未分配;它可能是二进制文件或其中一个库的一部分,甚至是尚未加载的数据段,因为程序还没有调用它;它可能已被换出到交换区域,以便为需要它的其他程序释放物理内存
  • shared vs private - 进程虚拟地址空间的只读部分(例如,程序的实际代码和大多数库)可以与使用相同库或程序的其他进程共享 - 这总体内存使用是一个很大的优势,因为运行37个不同的xterm实例并不意味着需要将xterm的代码加载到内存中37个不同的时间 - 所有进程可以共享一个副本代码

由于这些以及一些其他因素(IPC共享内存,内存映射文件,具有映射在硬件中的内存区域的物理设备等),确定任何单个进程使用的实际内存,甚至是整个系统,可能很复杂。