Memory 如何在C#托管代码中重新创建SOS.dll功能?SOS.dll ObjSize和DumpObject在后台是如何工作的?
我在这个问题上做了很多研究,但仍然感到困惑。我以前曾向stackOverflow提出过这个问题,但得到的答复不太令人满意。这让我相信这是一个相当高级的话题,需要对CLR有深刻的理解才能回答。我希望一位大师能帮助我 这个问题很大程度上是基于我以前的文章和发现 我正在尝试使用反射重新创建SOS.dll的一些功能。特别是Memory 如何在C#托管代码中重新创建SOS.dll功能?SOS.dll ObjSize和DumpObject在后台是如何工作的?,memory,reflection,clr,sos,Memory,Reflection,Clr,Sos,我在这个问题上做了很多研究,但仍然感到困惑。我以前曾向stackOverflow提出过这个问题,但得到的答复不太令人满意。这让我相信这是一个相当高级的话题,需要对CLR有深刻的理解才能回答。我希望一位大师能帮助我 这个问题很大程度上是基于我以前的文章和发现 我正在尝试使用反射重新创建SOS.dll的一些功能。特别是ObjSize和DumpObject命令。我使用反射查找所有字段,然后如果字段是基本类型,我将基本类型的大小添加到对象的总体大小中。如果字段是值类型,那么我递归调用原始方法并沿着引用树
ObjSize
和DumpObject
命令。我使用反射查找所有字段,然后如果字段是基本类型,我将基本类型的大小添加到对象的总体大小中。如果字段是值类型,那么我递归调用原始方法并沿着引用树遍历,直到找到所有基本类型字段
我一直得到比SOS.dll ObjSize
命令大两倍左右的对象大小。我发现的一个原因是我的反射代码似乎正在查找SOS忽略的字段。例如,在字典中,SOS查找的字段如下:
- 水桶
- 条目
- 计数
- 版本
- 自由列表
- 免费计数
- 比较器
- 钥匙
- 价值观
- _同步根
- 缪斯信息
- 版本名
- 哈西塞纳
- KeyValuePairsName
- 比较名称
- 字典-532B
- 水桶-40
- 参赛作品-364
- 比较器-12
- 钥匙-492
- (其余为空或基本)
- 对象包含名为FirstChar的属性
- 对象包含名为Chars的属性
- 对象包含名为Length的属性
- 对象包含名为m_stringLength的字段
- 对象包含名为m_firstChar的字段
- 对象包含名为空的字段
- 对象包含名为TrimHead的字段
- 对象包含名为TrimTail的字段
- 对象包含名为TrimBoth的字段
- 对象包含名为charPtrAlignConst的字段
- 对象包含名为alignConst的字段
有什么想法吗?或者如何获取索引属性的支持字段?索引属性是否应该包含在内存大小中?虽然这个想法很有趣,但我认为它最终是徒劳的,因为反射不能提供对对象实际存储的访问。反射允许查询类型,但不能查询它们的实际内存表示(这是CLR的一个实现细节) 对于引用类型,CLR本身向每个实例(MT和syncblk)添加内部字段。反射API不会显示这些内容。此外,CLR可以根据类型的定义对字段的存储使用任何类型的填充/压缩。这意味着原语类型的大小在不同的引用类型之间可能不一致。反射也不允许你发现这一点 简言之,反射无法发现产生正确结果所需的许多细节 你问了完全相同的问题。你到底为什么认为你会得到不同的答案?