gpt4 book ai didi

c# - 是否有一个 .Net 内存分析器可以跟踪大对象堆上的所有分配?

转载 作者:可可西里 更新时间:2023-11-01 07:48:28 25 4
gpt4 key购买 nike

关闭。这个问题不满足Stack Overflow guidelines .它目前不接受答案。












想改善这个问题吗?更新问题,使其成为 on-topic对于堆栈溢出。

3年前关闭。




Improve this question




我尝试过的大多数 .NET 内存分析器都允许您拍摄内存快照。

但是,我正在尝试诊断一个问题,即我最终分配给 .NET 的大量内存被 ANTS 分析器指示为“空闲”。 (我已经用 Mem Profiler 和 CLR Profiler 等其他分析器确认了这个问题。

ANTS 显示我有大量内存碎片(100% 的空闲内存,最大块为 150MB。)堆中所有对象的总大小为 180MB。我有 553 MB 分配给 .NET,152 MB 分配给“非托管”。

但是,大对象堆 (LOH) 的大小仅为 175kb。这是在那里分配的对象的实际大小。我不会分配任何最终在 LOH 上永久的对象。

因此,我的问题,在某些方面,我怀疑我正在以某种方式分配大对象(超过 LOH 的 85k 限制),然后处理它们。

我正在从数据库(Oracle、Sql Server)中读取大量数据(这里估计有几 MB),将这些数据复制到内存中的对象数组,并将数据处理成索引(数组、字典等)以便于搜索/过滤/处理。

我的猜测是,数据读取器暂时分配了大量空间。但是,我没有很好的方法来暂停程序并拍摄内存快照。

我想要的是一个分析器,它可以跟踪 LOH 上分配的每个对象 所以我可以弄清楚是什么导致了 LOH 碎片和过多的内存使用(内存没有返回给操作系统,所以看起来我的进程正在占用 1GB 的内存来存储 200MB 的分配对象。)我猜是内存没有返回,因为 LOH 没有被压缩,所以我在我的进程的生命周期中被所有这些内存困住了,这可能是数周(它作为 Windows 服务运行。)

编辑:我的问题是我的 .NET 应用程序使用了大量我无法追踪的内存。

Edit1:我使用了 Visual Studio 内存分析器。虽然它确实告诉我实例化的所有对象、多少、总字节数等,但我没有提示我为什么最终有这么多空闲内存。我唯一的提示/线索是 ANTS 告诉我的:“内存碎片正在限制可以分配的对象的大小。”我有很多未使用的内存分配给 .NET 没有使用。

Edit2:更多分析表明我在 LOH 上分配了一些短期存在的大对象。但是,在 LOH 上分配的总量永远不会超过 3 到 4 MB。然而,在这段时间里,私有(private)字节通过屋顶,翻了一番,翻了三番,而我实际分配的对象(在所有堆上)的大小只略有增加。例如,所有堆中的字节为 115MB,但我的私有(private)字节超过 512 MB。

ANTS 清楚地告诉我,我遇到了内存碎片问题。结果我在 LOH 上创建了短暂的对象。但是,这些对象的总大小不会超过 3 或 4 MB。所以这些短命的大物体(似乎?)正在 split LOH。

回应 Eric Lippert 和迪士尼乐园 parking 场的比喻(这很棒)。

这就像有人在一个地方 parking 几分钟,然后离开。然后保留该位置(没有其他人可以在那里 parking ),直到我重新铺设 parking 场!

当 Visual Studio 警告我内存使用情况并建议切换到 x64 时,我首先开始对此进行调查。 (我忘记了警告号码,快速谷歌没有找到)。因此,切换到 x64 可以缓解眼前的问题,但并没有解决根本问题。

就像我有一个可以停 1000 辆车的 parking 场,但是当我把 100 辆车放进去之后,我的 parking 服务员尖叫着说它已经满了......

幸运的是,我有一个庞大的 VMware 集群可供我使用,并且有一个懂行的管理员。我被分配了 8 个 cpu 和 8 GB 的内存。所以只要有问题,我可以处理,我只是投入资源。另外,(正如我上面所说的)我切换到 x64 一段时间,因为 Visual Studio 不断提醒我警告,但是,我想弄清楚它在 LOH 上分配的内容,看看我是否可以减轻这种堆碎片一些小的代码更改。也许是一个傻瓜的差事,因为我可以向它扔资源。

应用程序运行良好,速度很快,偶尔会出现 GC 暂停。但大多数情况下我可以忍受这种情况,我只想知道是什么物体导致了它。我的怀疑是一些我还没有找到的短期字典。

编辑3 :http://msdn.microsoft.com/en-us/magazine/cc188781.aspx

ObjectAllocatedByClass does not track allocations of the large object heap, but ObjectAllocated does. By comparing the notifications from the two, an enterprising soul should be able to figure out what is in the large object heap as opposed to the normal managed heap.



所以看起来这是可以做到的。但是,我的 C++ 技能很难深入研究(如果我有更多时间,可能在 future 某个时候)。我希望分析器能够提供这种开箱即用的功能。

最佳答案

经过试验,我能够在 GC 从一代中删除事物时收到通知,但在将其放入时却无法收到通知。

由于 LOH 不是特定于世代的,并且没有我可以访问的特定事件以获取 LOH 插入的通知,因此我可以提供的唯一替代方法是调试应用程序,进行故障转储 - 或者 - 在本地运行它并使用 WinDBG。您可以这样做:

  • 下载 Windows SDK 7
  • 将 %Microsoft_NET_Framework%\sos.dll 复制到 WinDBG 目录
  • 在 WinDBG 中单击文件 -> 打开可执行文件 -> 指向您的可执行文件
  • 在底部的命令栏中键入 g (去)
  • 监控内存,当你想分析它时,去 WinDBG -> 调试菜单 -> 中断
  • 类型 load .sos - 加载 .NET 扩展
  • 类型 !dumpheap -min 85000 - 这将列出应位于 LOH
  • 上的大型对象

             Address               MT     Size
    0000000012a17048 000007fee7ae6ae8 400032
    0000000012a78b00 000007fee7ae6ae8 400032
    0000000012ada5b8 000007fee7ae6ae8 400032
    0000000012b3c070 000007fee7ae6ae8 400032
    0000000012b9db28 000007fee7ae6ae8 400032


    接下来,我们需要逐一检查并找出其中的内容。
  • 将第一列(对象地址)复制到剪贴板
  • 类型 !do <paste from clipboard>
  • 这将列出对象的内容、类型和大小。

  • CLR Version: 4.0.30319.261
    SOS Version: 4.0.30319.239
    Name: System.String
    MethodTable: 000007fee7ae6ae8
    EEClass: 000007fee766ed68
    Size: 400026(0x61a9a) bytes
    File: C:\Windows\Microsoft.Net\assembly\GAC_64\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll
    String: 8470737076787475867884758166807183888774746571677189..
    Fields:
    MT Field Offset Type VT Attr Value Name
    000007fee7aec9d0 4000103 8 System.Int32 1 instance 200000 m_stringLength
    000007fee7aeb510 4000104 c System.Char 1 instance 38 m_firstChar
    000007fee7ae6ae8 4000105 10 System.String 0 shared static Empty
    >> Domain:Value 000000000055fe50:0000000002a11420 <<


    您要查找的行是:

    Size:        400026(0x61a9a) bytes
    String: 8470737076787475867884758166807183888774746571677189..

  • 为每个对象执行此操作

  • (但是,我假设它是一个字符串,因此请查看 'Name' 属性以确保它。它可能是一个数组。)

    关于c# - 是否有一个 .Net 内存分析器可以跟踪大对象堆上的所有分配?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9911788/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com