1

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

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

操作系统为 32 位

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

4

4 回答 4

3

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

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

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

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

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

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

或两者。或者两者都不是。

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

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

于 2010-07-27T16:37:40.417 回答
3

碎片化。

如果您分配以下内存块:

  • 16KB
  • 8KB
  • 16KB

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

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

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

于 2010-07-27T19:16:05.407 回答
1

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

于 2010-07-27T16:33:43.853 回答
1

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

例如,如果你有一个 ATL 服务,它默认自动启动 4*numberOfCores 个单元消息调度线程。用/STACK:12000000(12兆字节)编译和链接这样一个服务,然后在16核服务器上运行它,它将启动64个线程,每个线程有12MB​​的堆栈,立即消耗768MB的虚拟地址空间,虽然实际提交内存可能要低得多。

于 2012-04-08T04:13:58.133 回答