- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
这个问题很大程度上是基于我之前找到的帖子 here .
我正在尝试使用反射重新创建 SOS.dll 的一些功能。特别是 ObjSize
和 DumpObject
命令。我使用反射来查找所有字段,然后如果字段是原始类型,我将原始类型的大小添加到对象的整体大小。如果该字段是值类型,那么我将递归调用原始方法并沿着引用树向下走,直到找到所有原始类型字段。
我一直得到比 SOS.dll ObjSize 命令大两倍左右的对象大小。我发现的原因之一是我的反射代码似乎在寻找 SOS 忽略的字段。例如在字典中,SOS 查找以下字段:
但是我的反射代码找到了以上所有内容并且还找到了:
此外,我对在 SOS ObjSize 和 DumpObject 命令中发现的不一致感到困惑。我知道 DumpObject 不会查看引用类型的大小。但是,当我在上面提到的字典上调用对象大小时,我得到:
然后我在 Dictionary 上调用 DumpObject 来获取它的引用类型的内存地址。然后当我在它的引用类型上调用 Objsize 时,我得到:
顶级字典上的 ObjSize 不应该大致是字典内字段上所有 ObjSize 的总和吗?为什么 Reflection 找到的字段比 DumpObject 多?关于为什么我的反射分析返回的数字大于 SOS.dll 有什么想法吗?
另外,我在上面链接的线程中提出的问题之一从未得到答案。我问的是在评估对象的内存大小时是否应该忽略属性。普遍的共识是忽略它们。但是,我找到了一个很好的示例,说明属性的支持字段何时不包含在从 Type.GetFields() 返回的集合中。在 String 的内部进行查看时,您会发现以下内容:
对象包含名为 FirstChar 的属性对象包含名为 Chars 的属性对象包含名为 Length 的属性对象包含名为 m_stringLength 的字段对象包含名为 m_firstChar 的字段对象包含名为 Empty 的字段对象包含名为 TrimHead 的字段对象包含名为 TrimTail 的字段对象包含名为 TrimBoth 的字段对象包含名为 charPtrAlignConst 的字段对象包含名为 alignConst 的字段m_firstChar
和 m_stringLength
是属性 FirstChar
和 Length
的支持字段,但字符串的实际内容是在 Chars 属性(property)中举行。这是一个索引属性,可以对其进行索引以返回字符串中的所有字符,但我找不到包含字符串字符的相应字段。
有什么想法吗?或者如何获取索引属性的支持字段?索引属性是否应包含在内存大小中?
最佳答案
好吧,你的反射代码坏了。您提到的 4 个成员(VersionName 等)不是字段,它们是私有(private)常量。我猜您正在使用 Type.GetMembers() 而不是 Type.GetFields() 并且没有正确检查返回的 MemberInfo.MemberType 。只需使用 GetFields() 即可。
请注意,您永远无法获得托管对象的正确大小。对象的布局是不可发现的。大小不是字段的总和,字段对齐。与 StructLayout.Pack 属性非常相似。对齐会在布局中产生空洞,即所谓的“填充字节”。以及最后的额外填充,以便在类对象存储在数组中时对齐字段。
CLR 实际上利用了布局不可发现的事实。如果后面的字段适合其他两个字段之间的填充,它将交换字段。如果您知道对齐规则,则生成比您得到的对象更小的对象。尝试对此进行逆向工程是一项危险的工作,它还取决于架构(x86 vs x64 vs Arm)。
SOS.dll 没有这个问题,它可以直接访问 CLR 为类维护的内部数据。禁止使用托管代码。
关于c# - SOS.dll ObjSize 和 DumpObject 背后的复杂之处。如何在 C# 中重新创建 SOS.dll?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14483432/
我有一个 .NET .86 应用程序。我正在尝试从 cdb 运行 dumpdomain 但一直出现错误。 关于这个有很多问题,我尝试了几种变体: C:\Users\d.banks\Documents>
这个问题很大程度上是基于我之前找到的帖子 here . 我正在尝试使用反射重新创建 SOS.dll 的一些功能。特别是 ObjSize 和 DumpObject 命令。我使用反射来查找所有字段,然后如
我刚刚开始使用 windbg/sos,我创建了一个简单的控制台应用程序进行测试(抛出一个未处理的异常)。似乎在我加载 sos 之后,我会在下一次调用时遇到异常。 例如: ntsd consoleapp
嗨,SO 的智者。这是求救信号。 我遇到了很大的麻烦。在我的网络应用程序中有一个对象(假设它是对某事的请求)。用户提交他/她的请求。之后是可以批准/不批准该请求的人员。在从提交到批准/不批准的这段时间
我正在尝试使用 windbg 来研究在 x64 机器上为我们的 x86 进程创建的挂起转储文件。这是一个 4.0 x86 应用程序,所以为了获得非托管堆栈,我必须执行以下操作: .loadby sos
我现在正在将 SOS 调度程序从 sun solaris 迁移到 Oracle linux, SOS Berlin 调度程序是 1.5.3253 的最新版本 - Linux X64Java JDK 1
如何查看作为参数传入的日期时间? 我在互联网上找到了这个示例,但我在理解它时遇到问题?我根本看不到他们在哪里使用 clrstack 的输出,它只是说“通过向前转储 ESP 的内存来查看堆栈:” htt
如何在当前线程的 clrstack 上打印所有 System.String 对象的字符串值? 我想做的伪代码: foreach ($string in !dso -type System.String
我需要使用 WinDbg 调试 32 位托管应用程序,但是 WinDbg 顽固地拒绝加载 SOS.dll 扩展。经过许多互联网搜索和尝试后,我被难住了。我有使用 WinDbg 调试非托管代码的经验,但
我尝试在 vb.net 应用程序中加载 Visual Studio 2010 (.Net Framework 4) 中的 SOS 扩展,但没有成功。 首先我发现了以下article建议我在立即窗口中输
我使用了以下 sos 命令来枚举正在运行的 asp 应用程序(托管在 windows xp 4 GB 机器上)中特定类型的所有实例。 .foreach (obj { !dumpheap -type :
我制作了一个手电筒应用程序,现在我想添加 sos 莫尔斯电码闪烁。这是我的代码,但它工作得不太好,它闪烁得太快,所以我需要某种延迟,任何人都可以帮忙吗? public void sos(View v)
我正在通过 WinDBG 使用 SOS.dll 查看故障转储。给定一个 Dictionary 对象的地址,是否有一种简单的方法来转储它的内容,例如.. Key1 -> Value1 Key2 -> V
我正在尝试学习如何使用 Openlayers 和 SOS(传感器观察服务)服务。我在互联网上找到了几个例子,并研究了算法,但由于我对 Openlayers 库不太熟悉,而且我是 Javascript
关闭。这个问题需要details or clarity .它目前不接受答案。 想改进这个问题吗? 通过 editing this post 添加细节并澄清问题. 关闭 7 年前。 Improve t
我有一个 ASP.net 2.0 应用程序,我正在尝试使用 Windbg 和 SOS.dll 对其进行实时调试。 当我将调试器附加到进程时,我看到它同时加载了 2.0 和 4.0 版本的 CLR。
我最近从 native 代码编程切换到托管代码编程。我正在使用.NET。 由于我使用 Windbg 已经有一段时间了,我也想将它用于托管代码调试。 我的搜索将我带到了 SOS(罢工之子)扩展程序,它似
当我在 Visual Studio 的即时窗口中使用 .load SOS 并无意中发出了导致一长串输出的命令(例如 !dumpheap -type System.String -min 100)时,即
有一个question with the same title但不幸的是它对我没有帮助。 我正在尝试解析 SOS 标记的数据。我能找到的所有文档都说在标记( 0xFFDA )之后是一个两字节的数字,它
“罢工之子”这个名字有何意义?它有什么意义还是只是听起来很酷? 最佳答案 杰森·赞德的blog post完美地解释了这一点: The original name of the CLR team (ch
我是一名优秀的程序员,十分优秀!