c# windows app - 分析峰值内存使用情况并识别趋势

Posted

技术标签:

【中文标题】c# windows app - 分析峰值内存使用情况并识别趋势【英文标题】:c# windows app - profiling peak memory usage and identifying trends 【发布时间】:2009-07-08 11:50:41 【问题描述】:

我有一个运行时间很长的控制台应用程序,经过数百万次迭代。如果内存使用量随着迭代次数的增加而线性增加,我想进行基准测试

最好的方法是什么?

我认为我真的只需要在运行期间关注内存使用峰值,对吗?考虑到服务器上的内存,我基本上需要计算出我可以在此硬件上运行的最大迭代次数。

我将设置大量运行并记录不同交互大小的结果,然后绘制结果以确定内存使用趋势,然后可以针对任何给定硬件进行推断。

寻找实现这一点的最佳方式的建议,要使用哪些 .net 方法、类,或者我应该使用外部工具。这篇文章 http://www.itwriting.com/dotnetmem.php 建议我应该通过代码分析我自己的应用程序,以将 .net 运行时使用的共享内存分解出在盒子上的其他应用程序之间。

谢谢

【问题讨论】:

【参考方案1】:

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

Perfmon 用户界面

您可以使用 Windows 附带的 Performance Monitor 控制面板小程序(在管理工具中)来监控您的应用程序。查看 .Net CLR 内存类别和其中的计数器。您还可以将监控限制在您的过程中。这可能是最简单的,因为它不需要更改代码。

Perfmon API

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

内存分析器

您可以使用内存分析器在应用程序运行时对其进行分析。我成功使用的两个是 RedGate 的 ANTS Memory Profiler 和 SciTech 的 .Net Memory Profiler。同样,这不需要更改代码,但可能会花钱(尽管有免费试用版)。还有CLR Profiler(操作方法可以在here找到)。

自己动手

您可以从Process 类中获取一些有限的内存信息。使用Process.GetCurrentProcess()获取当前进程,然后查看它的属性,特别是与内存相关的属性(MinWorkingSet、MaxWorkingSet、PagedMemorySize64、PeakPagedMemorySize64、PeakVirtualMemorySize64、PeakWorkingSet64 、PrivateMemorySize64、VirtualMemorySize64、WorkingSet64)。这可能是最糟糕的解决方案,因为您必须自己做所有事情,包括数据收集和报告。


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

【讨论】:

谢谢阿德里安,我将选择“自己动手”选项。它适合我的情况,我需要运行一个应用程序,该应用程序在内部使用不同的参数(一个是迭代大小)执行多次运行,并且我需要独立分析每个运行而不是整个控制台应用程序。我想我会在每次运行之前和之后拍摄程序状态的快照(如果有必要,可能在每次运行期间拍摄,除非我可以使用峰值?以某种方式用于运行),然后计算使用的最大内存。在这种情况下,哪些属性和方法最好。谢谢 我原以为 WorkingSet64 和 PeakWorkingSet64 将是您需要使用的。这些给出了进程使用的当前和峰值内存。【参考方案2】:

Windows perfmon 非常适合这种东西。你有所有托管堆和私有字节的计数器,如果你需要与迭代计数交叉关联,你可以publish your own .Net 的 perfmon 计数器。

【讨论】:

【参考方案3】:

当您想要分析应用的内存使用情况时,可以使用以下代码。 首先你必须声明一个 PerformanceCounter 类的实例

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

每次你想记录内存消耗时,你可以调用

_PerfCounter.NextValue()

希望对你有帮助

【讨论】:

当我在上面运行此代码时,我得到:指定类别中不存在实例'IRC'。 IRC 是我的程序集名称,这里发生了什么? 尝试不使用调试器运行 (Ctrl+F5)【参考方案4】:

也许this tool 可以为所欲为。

【讨论】:

【参考方案5】:

迟到总比没有好,但为了响应 M3ntat 的评论,如果您从 Visual Studio 中运行,则需要将“.vshost”添加到程序集名称参数中,例如

a.GetName().Name + ".vshost"

【讨论】:

以上是关于c# windows app - 分析峰值内存使用情况并识别趋势的主要内容,如果未能解决你的问题,请参考以下文章

matlab中的内存监控

MoveItemAtPath 的内存峰值

Visual Studio 2010 性能分析能否与用 C# 编写的 Windows 服务一起工作

测量峰值堆栈指针值及其 PC 位置

怎么查看java程序运行的峰值内存消耗(含虚拟机)和CPU消耗(ms)

zabbix 3.2 监控Windows 实时内存使用率与CPU使用率