.net - 确定.NET中对象图的内存使用率

标签 .net memory memory-management

部分出于好奇——我们想知道在我们的应用程序中发生了什么——部分是因为我们需要在我们的代码中找到一些潜在的问题,我喜欢在我们的网络应用程序运行时跟踪一些一般值。这尤其包括某些对象图的分配内存。

我们的应用程序将一些数据永久保存在内存中以使其可靠可用。这可以加起来达到几 GB 的内存,而其他执行几乎相同任务的应用程序只分配一两个内存。

由于性能要求,我们无法在运行时附加内存分析器。 因此,如果在运行时分析一个对象图以打印出在某些情况下数据的哪些部分很大,哪些部分不太大,那就太好了。这将有助于我们更好地了解数据发生了什么,并可能优化我们应用程序的行为。

对象图意味着,从某个对象开始,测量它在内存中的大小,通过所有属性、字段、列表及其所有元素等递归地跟踪所有引用的对象,并添加它们相应的大小,直到我们知道这个对象和所有相关对象使用了多少内存。

其实,我想回答的问题是:当我刚刚释放对这个 anchor 对象的最后一个引用时,下次运行清理这个对象图时,GC 能够释放多少?

最佳答案

不清楚这是否满足您的要求,但 Windbg 的 SOS 扩展提供了 !objsize 命令来递归地确定对象的大小,包括所有引用的对象。您可以附加到正在运行的进程,或进行内存转储(例如使用 procdump),然后附加到转储文件以执行脱机分析。但是,如果子对象可以从您的初始对象访问,则 !objdump 的输出将只是您最后一个问题的答案(任何其他引用当然会阻止即使您的初始对象变得无法访问,子对象树也不会被收集。

从流程本身来看这如此困难的部分原因是运行时必然隐藏了很多关于内存中表示的细节。其中一些可以通过使用不安全代码来克服,但它仍然很重要,因此在 Windbg 中使用类似 SOS 的东西“知道”CLR 的内部结构使得这个过程变得更加容易,但明显的限制是它必须从过程的“外部”完成,而不是从内部完成。

关于.net - 确定.NET中对象图的内存使用率,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26262599/

相关文章:

c# - 错误调用函数,[对 PInvoke 函数的调用使堆栈不平衡]

c++ - 正确删除EGL Opengles 2.0

iphone - AVCaptureStillImageOutput 输出设置内存泄漏

c++ - 如何使用不同的指针算术语义

java - Java相关的Native内存是如何被清除的。我了解 GC 不会清除它

c++ - 如何判断一个对象是在构造函数上静态分配还是动态分配?

java - 为什么这个java进程不释放内存?

c# - LINQ to Entities 无法识别方法 Generic.List(int) 到 Generic.IEnumerable(int) 方法

c# - 加载任何表单时运行事件

c# - 这是代码契约(Contract)重写器中的错误吗?