计数(非垃圾收集)对象的方式

Way of counting (non. Garbage collected) objects

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

有什么方法可以从我的应用程序代码中定期计算应用程序中当前存在的对象数量吗?

该问题不能一概而论,但是,您可以尝试以下方法之一:

  • Pause/freeze 您的应用程序并创建进程的内存转储(假设您使用的是 Windows,您可以使用任务管理器的详细信息窗格和 right-click任何进程并使用命令 Create dump file.
    然后您可以使用 Visual Studio 打开转储文件,它可以自动 re-create 内存堆。

  • 使用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" 如何获取堆对象的大小和布局。

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