应用程序的虚拟字节增长为私有字节的 2 倍。
这是否表明内存泄漏?糟糕的应用程序设计?
操作系统为 32 位
欢迎任何想法。应用程序是流数据库。
应用程序的虚拟字节增长为私有字节的 2 倍。
这是否表明内存泄漏?糟糕的应用程序设计?
操作系统为 32 位
欢迎任何想法。应用程序是流数据库。
应用程序的虚拟字节增长为私有字节的 2 倍。
如果应用程序只分配堆,那么对我来说,这将是应用程序分配大量内存但从未真正触及它的标志。例如:
void *p = malloc( 16u<<20 );
会吃掉 16MB 的虚拟内存。但只要应用程序不对内存块执行任何操作,操作系统甚至不会尝试将虚拟内存映射到 RAM。强制实际分配私有内存的最简单方法是 memset() 它:
void *p = malloc( 16u<<20 );
memset( p, 0, 16u<<20 );
这是否表明内存泄漏?糟糕的应用程序设计?
或两者。或者两者都不是。
响应的较长变体:未知,取决于应用程序分配的内存、应用程序使用的其他资源、操作系统、硬件平台等。
如果不确定,请使用内存泄漏分析工具进行调查,例如valgrind。阅读 SO 以获取有关C++ 中内存泄漏分析的更多信息。
碎片化。
如果您分配以下内存块:
然后释放 8KB 块,您的应用程序将拥有 32 KB 的私有字节,但有 40 KB 字节的虚拟内存,这实际上是您的进程使用过的最高虚拟内存地址(忽略其他内存部分为了简单起见)。
考虑(如果可能)使用另一个内存管理器。一些替代方案是:
第四种选择是编写自己的内存管理器。这并不容易,但如果做得好,它可以带来相当多的好处。特别是对于某些利基或特殊应用程序,编写自己的内存管理器可能很有用。
内存分配有开销来存储有关分配内容的管理信息。如果您分配的缓冲区非常小,则额外信息可能占总数的很大一部分。这可能就是你所看到的。
一种可能性是,如果您使用链接器选项 /STACK:reserve_bytes 为线程设置较大的堆栈保留大小,然后启动大量线程。
例如,如果你有一个 ATL 服务,它默认自动启动 4*numberOfCores 个单元消息调度线程。用/STACK:12000000(12兆字节)编译和链接这样一个服务,然后在16核服务器上运行它,它将启动64个线程,每个线程有12MB的堆栈,立即消耗768MB的虚拟地址空间,虽然实际提交内存可能要低得多。