C# Windows应用程序-分析峰值内存使用率并确定趋势

3
我有一个长时间运行的控制台应用程序,经过数百万次迭代。我想要测试内存使用量是否随着迭代次数的增加呈线性增长,请问最好的方法是什么?
我认为我只需要关注运行期间的峰值内存使用情况,对吗?基本上我需要计算出在这台服务器上可以运行的最大迭代次数,考虑到服务器内存。
我将设置一批运行并记录不同迭代大小的结果,然后绘制结果图以确定内存使用趋势,从而可以对任何给定的硬件进行推断。
寻求关于实现此目标的最佳方法的建议,包括应该使用哪些 .net 方法、类或者是否应该使用外部工具。这篇文章http://www.itwriting.com/dotnetmem.php建议通过代码分析自己的应用程序来消除在盒子上的其他应用程序共享的 .net 运行时使用的内存。
谢谢
5个回答

6

有几种方法可以做到这一点:

Perfmon UI

您可以使用随 Windows 附带的性能监视器控制面板应用程序(在“管理工具”中)来监视您的应用程序。查看 .Net CLR Memory 类别和其中的计数器。您还可以将监视限制为仅适用于您的进程。这可能是最简单的,因为它不需要进行代码更改。

Perfmon API

您可以从 .Net 中编程使用性能计数器。为此,您需要使用 PerformanceCounter 类。这只是上述 UI 呈现的相同基础信息的 API。

Memory Profiler

您可以使用内存分析器来在应用程序运行时对其进行分析。我成功使用过的两个工具是RedGate的ANTS Memory Profiler和SciTech的.Net Memory Profiler。同样,这不需要任何代码更改,但可能需要您花费一些钱(尽管有免费试用版本)。还有CLR Profiler(如何使用请见此处)。

自己动手

您可以从 Process 类中获取一些有限的内存信息。使用 Process.GetCurrentProcess() 获取当前进程,然后查看其属性,特别是与内存相关的属性(MinWorkingSetMaxWorkingSetPagedMemorySize64PeakPagedMemorySize64PeakVirtualMemorySize64PeakWorkingSet64PrivateMemorySize64VirtualMemorySize64WorkingSet64)。这可能是最糟糕的解决方案,因为您必须自己完成所有工作,包括数据收集和报告。


如果你只是想验证你的应用程序在迭代次数增加时不会线性增加其内存使用量,我建议在Windows中使用性能监视器UI进行监控。它将以最小的努力向你展示你所需的内容。

谢谢Adrian,我将选择“自己动手”选项。这适合我的情况,我需要运行一个应用程序,该应用程序在内部使用不同的参数(其中之一是迭代大小)执行多个运行,并且我需要独立地分析每个运行而不是整个控制台应用程序。我想在每次运行之前和之后(如果必要,在每次运行期间)拍摄程序状态的快照,然后计算最大内存使用量。在这种情况下,哪些属性和方法最好?谢谢 - m3ntat
我本以为WorkingSet64和PeakWorkingSet64是您需要使用的。它们提供了进程当前和峰值内存使用情况。 - adrianbanks

3

Windows perfmon非常适合这种情况。您可以使用所有托管堆和私有字节的计数器,如果需要与迭代计数相关联,可以从.Net发布自己的perfmon计数器。


1

当您想要分析应用程序的内存使用情况时,这里有一段代码可以使用。 首先,您需要声明 PerformanceCounter 类的一个实例。

Assembly a = Assembly.GetExecutingAssembly();
_PerfCounter = new PerformanceCounter(".NET CLR Memory",
                                      "# Bytes in all Heaps",
                                      a.GetName().Name,
                                      true);

每次您想要记录内存使用情况时,都可以调用

_PerfCounter.NextValue()

希望这对你有所帮助


1
当我运行上面的代码时,我得到了以下错误信息:在指定的类别中不存在实例“IRC”。IRC是我的程序集名称,这里发生了什么? - m3ntat
尝试不使用调试器运行(Ctrl + F5) - Konstantin Spirin

0
比不做好晚做好,但是针对M3ntat的评论,如果你在Visual Studio中运行,你需要将".vshost"添加到程序集名称参数中,例如:
a.GetName().Name + ".vshost"

0

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