在运行时轮询C#应用程序的内存使用情况?

19

我有一个应用程序在运行时需要轮询自己的内存使用情况。如果能够列出每个实例化对象的内存使用情况,那就更理想了。我知道这可以通过 WMI 实现,但我希望有一种不依赖于 WMI 的方法。

5个回答

阿里云服务器只需要99元/年,新老用户同享,点击查看详情
29

你可能会发现两个有用的函数:

  GC.GetTotalMemory();
  Process.PagedMemorySize64();

我的经验是GC.GetTotalMemory()并不十分可靠。它经常报告比实际内存使用量小得多的内存使用情况。我曾看到它报告我只使用了8GB内存,而我的程序在16GB机器上耗尽了内存。

虽然我还没有测试过Process.PagedMemorySize64,但它看起来很有前途。


1
我认为Process.PrivateMemorySize64()是用于活动内存使用的正确方法。 - maxfridbe
3
我不确定在什么情况下Process.PagedMemorySize64有用,但在我的情况下它并没有起作用。我在一些对象被实例化和解析器运行之前/之后进行比较,而PagedMemorySize64在之前和之后都报告相同的值,而GC.GetTotalMemory(true)似乎更有效地报告了内存使用量的变化。 - Steve Wortham
https://dev59.com/sXRB5IYBdhLWcg3wAjNH - Lost_In_Library
2
@SteveWortham 各种进程属性(例如PagedMemorySize64)都被缓存,因此仅仅再次访问它们并不会给你新的值。Process.Refresh()旨在清除缓存并获取新的数字,但我发现它不起作用。然而,每次实际创建一个新的进程对象(System.Diagnostics.Process.GetCurrentProcess())就可以解决问题。虽然不是理想的方法,但确实有效。 - coffeetocode
1
我同意Steve的观点,即使答案中提到了潜在的缺陷,GC.GetTotalMemory(true)似乎是正确的选择。当我在方法内部分配内存并从该方法返回时,该内存实际上被释放以便重复使用,但只有GC.GetTotalMemory(true)能够识别这一点。 - Dan W

6
Process proc = Process.GetCurrentProcess();
Logger.Info(proc.PeakWorkingSet64/1024 + "kb");

2

您可以监听perfmon计数器,这将为您提供大量数据(GC活动/物理内存使用情况/托管堆等)。

如果您需要更深入的了解,可能需要将调试器附加到自己身上,这非常棘手,因为您将不得不生成一个新进程并与其通信,并遍历您的内存。


2

0

可能

Windows::System::Diagnostics::ProcessDiagnosticInfo::GetForCurrentProcess();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,