【问题标题】:Way of counting (non. Garbage collected) objects计数(非垃圾收集)对象的方式
【发布时间】:2018-07-22 01:54:24
【问题描述】:

我在生产应用程序中存在内存泄漏。该应用程序将运行良好,然后突然内存将急剧下降。由于我无法控制的原因,我无法附加正常的内存分析器(如 dotMemory)。

是否有某种方法可以在我的应用程序代码中定期计算应用程序中当前存在的对象的数量?

【问题讨论】:

  • 您是否考虑过进行内存转储并检查它?
  • 只需获取 WinDbg,从进程中获取转储并检查它。准备好重新启动进程并在内存使用仍低于 2-3 GB 时尝试进行内存转储(否则所有工具都需要很长时间来分析它)。
  • 如果 WinDbg 太陡而无法学习,请先尝试 DebugDiag。
  • 感谢您的建议。不幸的是,出于同样的原因,我无法附加分析器,我无法获得内存转储(技术原因、安全性、正常运行时间要求和大量政治因素的结合)。我试过了……

标签: c# debugging memory-leaks garbage-collection profiling


【解决方案1】:

这个问题不能用笼统的回答来回答,但是,您可以尝试以下方法之一:

  • 暂停/冻结您的应用程序并创建进程的内存转储(假设您使用的是 Windows,您可以使用任务管理器的详细信息窗格并右键单击任何进程并使用命令Create dump file
    您可以然后使用 Visual Studio 打开转储文件,它可以自动重新创建内存堆。

  • 使用 Visual Studio 自己的内存分析器。它可以检查所有堆对象、它们的大小、计数、类型等。有关详细信息,请参阅https://docs.microsoft.com/en-us/visualstudio/profiling/memory-usage?view=vs-2022

  • 使用外部分析工具没关系,你说那是不可能的

  • 实现您自己的对象计数器(假设您正在计算自己的对象):

    // a dataset of all object informations you want to store
    public record ObjectInfo(
        DateTime DateTimeAllocated,
        Type Type,
        ...
    )
    
    public abstract class profilable_object
        : object
    {
        public static readonly ConcurrentDictionary<profilable_object, ObjectInfo> Heap = new();
    
    
        public profilable_object() =>
            Heap[this] = new(DateTime.Now, GetType(), ...);
    
        ~profilable_object() => Heap.TryRemove(this, out _);
    }
    

    然后让你的所有类继承自profilable_object。然后,您可以使用静态字段 profilable_object.Heap 检查您的“堆”。
    看看this file from the GitHub project "sharplab.io" 了解如何获取堆对象的大小和布局。

    不用说,这种解决方案会严重影响性能,只能作为最后的手段。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-11-08
    • 1970-01-01
    • 2012-10-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多