什么可能是虚拟字节增长2x私有字节的原因?

时间:2010-07-27 13:43:12

标签: c++ memory-leaks resources virtual-memory

应用程序的虚拟字节增长为专用字节的2倍。

这是否表示内存泄漏?糟糕的应用程序设计?

操作系统是32位

欢迎任何想法。 应用程序是流数据库。

4 个答案:

答案 0 :(得分:3)

  

应用程序的虚拟字节增长为专用字节的2倍。

如果应用程序只分配堆,那么对我来说,这将是应用程序分配大量内存但从未真正触及它的标志。例如:

void *p = malloc( 16u<<20 );

会占用16MB的虚拟内存。但只要应用程序不对内存块执行任何操作,操作系统甚至不会尝试将虚拟内存映射到RAM。强制实际分配私有内存的最简单方法是memset()它:

void *p = malloc( 16u<<20 );
memset( p, 0, 16u<<20 );
  

这是否表示内存泄漏?糟糕的应用程序设计?

或两者兼而有之。或两者都没有。

响应的较长变体:未知,取决于应用程序分配的内存,应用程序使用的其他资源,操作系统,h / w平台等。

如果不确定,请使用内存泄漏分析工具进行调查,例如: valgrind。有关memory leak analysis in C++的更多信息,请阅读SO。

答案 1 :(得分:3)

碎片。

如果您分配以下内存块:

  • 16KB
  • 8KB
  • 16KB

然后你释放8KB的块,你的应用程序将有32 KB的私有字节,但是40 KB字节的虚拟内存,这实际上是你的进程使用过的最高虚拟内存地址(忽略了其他内存部分为了简单起见。)

考虑(如果可能)使用另一个内存管理器。一些替代方案是:

第四种选择是编写自己的内存管理器。这并不容易,但如果做得好,它可以带来很多好处。特别是对于某些特定应用或特殊应用,编写自己的内存管理器非常有用。

答案 2 :(得分:1)

内存分配存在管理有关分配内容的管理信息的开销。如果您要分配非常小的缓冲区,则额外信息可能占总数的很大一部分。那可能就是你所看到的。

答案 3 :(得分:1)

一种可能性是,如果使用链接器选项/ STACK:reserve_bytes为线程设置较大的堆栈保留大小,则会启动大量线程。

例如,如果您有ATL服务,它默认会自动启动4 * numberOfCores公寓消息调度线程。使用/ STACK:12000000(12兆字节)编译和链接此类服务,然后在16核服务器上运行它将启动64个线程,每个线程具有12MB​​堆栈,立即消耗768MB的虚拟地址空间,尽管实际提交记忆可能要低得多。