【发布时间】:2016-07-19 10:13:16
【问题描述】:
我制作了一个始终在 x64 机器上运行的 32 位 c++ 程序。一个客户说运行这个进程的 5 个实例正在使用导致他们所有的 24 GB RAM 都被使用。
我立即认为存在内存泄漏,但我无法重现此内存问题。
我发现Memory Limits for Windows 对内存分配进行了更多研究。这告诉我操作系统不允许 32 位进程使用超过 2 GB 的内存。
在 64 位窗口上的 32 位应用程序是否有可能使用超过 2 GB 的内存泄漏?
附:终止进程会导致内存恢复到正常运行级别(大约 2 GB)。
[编辑] 我现在看到大部分正在使用的内存是内核内存:非分页。这是否意味着它正在使用某些系统资源而不是内存泄漏?
[更新] 问题不是驱动程序或内存泄漏。这似乎是一个进程句柄泄漏。有一些东西不断地为文件启动新的句柄。这是使用 perfmon 监视进程时发现的。根据经验,如果一个进程有超过 2000 到 3000 个句柄,您应该进行调查。特别是如果这个数字每隔几秒就增加一次。
【问题讨论】:
-
您不能安装 Windows 64 位并使用他们的数据集重新测试或检索转储和分析吗?这将为您省去很多麻烦...
-
我也在使用 Windows 64。我查看了崩溃时的进程转储。它告诉我它试图访问一个内存位置但它不能。我怀疑它只是内存不足,当我尝试分配一些内存时它崩溃了。
-
是的,池内存 = 驱动程序。使用 poolmon/xperf/WPA 分析池内存使用情况:superuser.com/a/674725 以查看是哪个驱动程序导致的
-
消耗 24GB 的非分页池是不可能的。您没有收集正确的统计数据。让一个 32 位进程占用许多 GB 的 RAM 并不是很困难,只需以非常高的速率写入文件即可。确定为进程分配多少 RAM 以及为文件系统缓存分配多少内存是操作系统的职责。它从不故意避免使用 RAM。
-
所以我发现了问题。一个进程绑定到一个固定端口。当下一个进程打开时,它会每隔 500 毫秒尝试绑定到同一个端口。该线程每次尝试都会创建一个新句柄。线程句柄泄漏被存储在非分页池内存中。在 16 GB ram pc 上,这填满了所有内存,我的进程没有任何东西可以使用,这导致它崩溃。添加了绑定尝试限制来解决问题。
标签: c++ memory memory-management memory-leaks 32bit-64bit