You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用WinDbg计算内存转储中.NET 6缓存的ConcurrentDictionary保留大小?

获取.NET 6 ConcurrentDictionary缓存的精确内存占用方案

用WinDbg结合SOS扩展计算保留大小

完全可以用WinDbg获取ConcurrentDictionary的完整保留大小,步骤如下:

  1. 生成完整内存转储:
    • 用任务管理器右键目标进程,选择“创建转储文件”;或者在WinDbg中附加进程后执行命令:
      .dump /ma full_cache_dump.dmp
      
      /ma参数确保生成包含所有内存的完整转储。
  2. 加载SOS调试扩展:
    执行命令加载.NET调试扩展(针对.NET Core/.NET 6,需匹配运行时版本):
    .loadby sos coreclr
    
  3. 定位ConcurrentDictionary实例:
    用!dumpheap命令筛选出目标字典类型的实例:
    !dumpheap -type System.Collections.Concurrent.ConcurrentDictionary
    
    从输出中找到你要分析的字典实例的内存地址(比如0x0000021a3f45e0c0)。
  4. 计算保留大小:
    用!objsize命令计算该实例及其所有依赖对象的总内存占用:
    !objsize 0x0000021a3f45e0c0
    
    这个结果包含字典内部的数组、键值对结构、CacheItem值类型实例,以及CacheItem中引用的byte[]等所有关联数据。

    注意:如果缓存中的byte[]等对象被其他代码引用,!objsize会重复计算这部分内存。若要得到字典独占的内存,需结合支配树分析。

  5. 细致拆分分析:
    若要查看内部结构的大小分布,用!dumpobj命令查看字典的内部字段:
    !dumpobj 0x0000021a3f45e0c0
    
    找到内部的m_tables等数组字段,再对这些数组地址执行!objsize或!dumpheap,逐个统计各部分的内存占用。

其他可用工具

dotMemory

JetBrains的dotMemory可以直观分析内存快照:

  • 生成快照后,在对象列表中找到目标ConcurrentDictionary实例,查看保留大小(Retained Size),该值就是字典及其所有独有依赖对象的总内存。
  • 支持展开对象树,查看每个CacheItem、内部数组、byte[]的具体大小,还能通过支配树排除共享引用的对象,结果精准。

Visual Studio内存诊断工具

  • 在Visual Studio中启动调试,点击“调试”->“内存快照”生成快照。
  • 在内存分析器的“对象”视图中找到ConcurrentDictionary,查看其保留大小,还能对比多个快照分析内存变化趋势。

dotnet-dump命令行工具

适合无GUI的服务器环境:

  1. 用以下命令生成转储:
    dotnet dump collect -p <进程ID>
    
  2. 进入分析模式:
    dotnet dump analyze <转储文件路径>
    
  3. 同样使用SOS命令(如!objsize、!dumpheap)计算保留大小,操作逻辑和WinDbg一致。

额外注意点

  • 你的CacheItem是值类型,它会直接存储在ConcurrentDictionary的内部数组中,而非作为独立引用对象,所以!objsize会包含这些值类型实例本身的大小(包括字段对齐、填充等内存开销)。
  • 若要获取最精准的独占内存,优先使用工具的支配树功能,它会排除被其他对象共享引用的部分。

内容的提问来源于stack exchange,提问作者Denis

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 20:13:30