如何在win32进程中显示'使用的内存'的百分比?

时间:2010-03-24 19:42:50

标签: windows memory winapi memory-management

我知道内存使用在Windows上是一个非常复杂的问题。

我正在尝试为大型应用程序编写一个UI控件,显示“使用的内存百分比”数字,以便向用户显示可能是时候清理某些内存,或者更有可能重新启动应用。

一个实现使用来自MEMORYSTATUSEX的ullAvailVirtual作为基础,然后使用HeapWalk()来遍历进程堆以寻找额外的可用内存。 HeapWalk()步骤是必需的,因为我们注意到在运行分配并由堆释放的内存一段时间之后,ullAvailVirtual号从未返回并报告。经过数小时的密集工作后,ullAvailVirtual号码将不再准确报告可用内存量。

然而,这种方法被证明并不理想,因为即使进程堆没有被破坏,HeapWalk()偶尔也会返回奇怪的错误。此外,由于这是一个UI控件,堆行走代码每5-10秒执行一次。我曾尝试联系微软,了解HeapWalk()失败的原因,通过MSDN升级案例,但除了“你可能不应该这样做”之外,从未得到过答案。

因此,作为第二个实现,我使用PROCESS_MEMORY_COUNTERS中的PagefileUsage作为基础。然后我使用VirtualQueryEx遍历虚拟地址空间,将所有不是MEM_FREE的区域相加,并返回GetMappedFileNameA()的值。我的想法是,PageFileUsage本质上是“私有字节”,所以如果我将该进程使用的DLL的总大小添加到该值,那么它将是我的进程使用的内存量的一个很好的近似值。

第二种方法似乎(sorta)工作,至少它不会像堆walker方法那样导致崩溃。但是,如果启用了这两种方法,则值不相同。所以其中一种方法是错误的。

那么,StackOverflow世界......你将如何实现这个?

  • 哪种方法更有前景,或者你有第三种更好的方法?
  • 我应该回到原来的方法,并进一步调试奇怪的错误吗?
  • 我应该每隔5-10秒远离堆积物吗?

请记住,重点是向用户表明它正在变得“危险”,他们应该释放内存或重新启动应用程序。也许'使用百分比'不是这个问题的最佳解决方案?什么是?我的另一个想法是基于颜色的系统(红色,黄色,绿色,我可以基于更多因素而不仅仅是一个数字)

3 个答案:

答案 0 :(得分:1)

是的,Windows内存管理器经过优化,可以快速有效地满足内存请求,优化,可以轻松测量使用的空间。第一个缺点是发布的堆块很少被取消映射。它们只是标记为“免费”,供下一次分配使用。这就是VirtualQueryEx()无法工作的原因。

HeapWalk的问题在于你必须锁定堆(HeapLock),以便它可以在不改变堆分配的情况下运行它。这种锁可能会产生非常有害的副作用。引用:

  

走一堆可能会降级   性能,特别是对称性   多处理(SMP)计算机。该   副作用可能会持续到   过程结束。

即使这样,你得到的数字也毫无意义。程序永远不会耗尽可用空间,它会耗尽足够大的连续内存块来满足请求。我很害怕,没有快乐的答案。除了一个:64位操作系统的成本不到200美元。

答案 1 :(得分:0)

开始的地方可能是GetProcessMemoryInfo()。这将为您填充一个结构,其中包含当前工作集(以字节为单位)。

答案 2 :(得分:-1)

查看以下文章.NET and running processes

它使用WMI检查进程的内存使用情况,特别是使用

System.Diagnostics.Process

以及如何在C#中使用WMI的另一个链接:WMI Made Easy for C#

希望这有帮助。