【问题标题】:How to measure memory usage of a code?如何测量代码的内存使用情况?
【发布时间】:2023-11-26 22:31:01
【问题描述】:

我正在尝试测量代码的内存使用情况,但我不知道如何继续。 我不想使用“DotMemory”或任何我需要通过编程来完成的“分析器”。

有什么方法可以知道分配了多少对象? 比如 5 int(4 bytes) + 4 Object (16 bytes) ...

我用过

process.WorkingSet64

但每次我运行相同的代码时,我都会得到不同的值。

那么衡量代码内存使用情况的最佳方法是什么?

【问题讨论】:

  • DotMemory 之类的分析工具要花钱有一个很好的理由,因为收集保留的内存总量不仅仅是计算程序中的任何对象占用空间。还为 .NET self 保留了一些内存,这在工作集中被考虑在内。
  • 但是为什么即使我使用 DotMemory 或 CLRprolfiler 运行相同的代码,分配大小也会不同?
  • 因为如前所述,WorkingSet 也代表 .NET 本身使用的内存。
  • 不一样,因为值还包括系统库,不仅代码部分在工作

标签: c# .net memory


【解决方案1】:

.NET 是托管内存环境。这意味着分配和释放对您来说是透明的,但这也意味着内存使用模式不是完全确定的。

99.9% 的时间,这根本不是问题。其余时间,您应该将工作重点放在重要的领域 - 通常,在一个地方处理所有关键负载非常容易。

您的问题表明您来自 C/Pascal 背景 - 托管内存的权衡是您不应该真正关心内存 - 当然,您要注意不要完全浪费内存,但通常不会因为绝对必要而占用两倍的内存。 “之前的内存”和“之后的内存”是一个在多线程环境中实际上没有多大意义的问题 - 您的方法并不是唯一同时运行的方法。

【讨论】:

  • 但是如果我想知道为 methodX() 之类的代码创建了多少对象,我想知道 5 Int(大小 10 字节)+ + 4 对象(16 字节).. 和所以他们有什么方法可以做到这一点,比如使用反射或其他东西?
  • @omega 只有调试器才能真正访问它。当然,您不能从 .NET 应用程序实现探查器/调试器接口。如果您正在调查内存问题,只需使用 CLRProfiler。如果您需要在应用程序本身中 中的实时内存信息,那么您正在做一些严重错误的事情。这不是 C/Pascal,你不应该一直监控内存。这不再是你的工作了 - 除了分析之外。
【解决方案2】:

简单又傻:

long total = GC.GetTotalMemory(true);

【讨论】:

  • 这并没有向我们显示代码的特定部分使用的内存。
  • @EmpereurAiman 原始问题没有这样的要求。另外,我们可以调用这个方法,然后执行部分代码,然后再次调用该方法。不同的是这部分代码的内存消耗。
【解决方案3】:

正如其他帖子所述,您不能只查看您在流程资源管理器中看到的数字。

如果您真的想测量 MemoryUsage,建议使用适当的工具,例如 RedGate Ants ProflerdotMemory。还有很多,但是通过这两个我已经取得了很好的经验。 他们还向您展示了how many instances of each type 一个 in ram 和 what do hold them alive

主要问题是你看这个的原因是什么?你有内存问题吗?也许是泄漏? 在搜索问题时,常见的方法是使用上述工具制作快照并进行比较。在那里,您可以看到实例数量是否在增加。

要获得对象及其大小的近似值(例如,查看您是否会遇到问题),您可以尝试计算估计值,请参见 find size of object instanc in bytes in c sharp 示例

【讨论】:

  • 这不等同于使用分析器(因为 OP 不想使用)?
  • @boas 这样做的原因是每次都要进行单元内存测试,我们必须确保代码消耗相同的内存来确定代码是否正常?
【解决方案4】:

如果您需要以编程方式测量内存消耗,您可以使用dotMemory Unit 当前版本可以通过 ReSharper 单元测试运行程序与单元测试一起使用,但很快就会提供具有独立运行程序的下一个版本。

var mcp1 = dotMemory.Check();
methodX();
dotMemory.Check(memory =>
{
  var newObjects = memory.GetDifference(mcp1).GetNewObjects();
  var createdObjectsCount = newObjects.ObjectsCount;
  var allocatedMemory = newObjects.SizeInBytes;
});

更多详情请关注blog post

更新:独立跑步者进入 EAP https://www.nuget.org/packages/JetBrains.DotMemoryUnit/2.0.20150727.161305-EAP5

【讨论】:

  • OP 明确不想使用 DotMemory。
  • @BIBD 'dotMemory Unit' 不是 dotMemory。它是一个框架而不是一个应用程序。
最近更新 更多