c# - 通过 SOS 调查 CLR

标签 c# .net clr

目前,我正在深入研究 CLR,并尝试找到托管对象的适当大小。

我有两种简单的类型:

X类

    class XClass
{
    public XStruct StructField = new XStruct();
    public int IntField;
    public double DoubleField;
}

XStruct

struct XStruct
{
    public short ShortField;
    public long LongField;
}

还要考虑涉及此对象的代码片段:

static unsafe void Main(string[] args)
{
    double angle = 0.34;

    {
        double anotherDouble = 1.49;

        XStruct xStruct = new XStruct();
        xStruct.ShortField = 12;
        xStruct.LongField = 1234567890;

        XClass classObject = new XClass();
        classObject.DoubleField = angle + anotherDouble;
        classObject.IntField = 123;
        classObject.StructField = xStruct;

        <<<<<<<<BREAKPOINT>>>>>>>

        xStruct.ShortField = 3;
    }

    double* ptr = &angle;

    Console.WriteLine(*(ptr - 1));
    Console.ReadKey();
}

因此,我尝试获取有关放置在堆栈中的 XStruct 的一些信息,但我在那里找不到它。

!dso
PDB symbol for clr.dll not loaded
OS Thread Id: 0x1f94 (8084)
ESP/REG  Object   Name
0018EF1C 0260252c ConsoleApplication2.XClass
0018EF20 0260252c ConsoleApplication2.XClass
0018F290 0260252c ConsoleApplication2.XClass
0018F2C4 0260251c System.Object[]    (System.String[])
0018F2E0 0260252c ConsoleApplication2.XClass
0018F2E8 0260252c ConsoleApplication2.XClass
0018F30C 0260251c System.Object[]    (System.String[])
0018F3C0 0260251c System.Object[]    (System.String[])
0018F51C 0260251c System.Object[]    (System.String[])
0018F554 0260251c System.Object[]    (System.String[])
0018FA90 02601238 System.SharedStatics

请解释为什么 ConsoleApplication2.XStruct 未显示以及为什么 ConsoleApplication2.XClass 在堆栈中显示为对象。我认为 XClass(作为普通引用类型)应该放置在堆中。或者可能是我对 !dso 的理解不正确。

谢谢。

最佳答案

!dso == 转储堆栈对象。关注“对象”,结构体不是对象。

SOS 能够查找对象引用的唯一原因是它可以使用编译方法时抖动生成的元数据。当垃圾收集器执行堆栈遍历以查找回对象引用时,垃圾收集器将使用此数据。您可以在this answer中阅读更多相关信息。 。此元数据中缺少值类型值,GC 不关心它们。

您可以通过创建结构体数组来推断结构体的大小,并为结构体的第一个字段指定一个独特的值。用VS调试器查看数组,Debug + Windows + Memory + Memory1,将变量名放在Address字段中。您将结构值返回到十六进制转储中,位于数组头之后。请注意,结构大小取决于 CLR 版本和进程的位数,因此仅将此信息用作提示。

关于c# - 通过 SOS 调查 CLR,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24350717/

相关文章:

c# - 我如何在 ASP.net 中使用 ApplicationUserManager?

c# - 将十进制列表转换为由分隔符 (',' 分隔的字符串)

c# - 为什么 .net 中的数组只实现 IEnumerable 而不是 IEnumerable<T>?

c# - .NET/C#中如何在右键菜单上绘制?

c# - LINQ 选择相隔 X 分钟的记录

c# - 想知道从Web服务返回错误

c# - 在程序集加载时初始化库

c# - 为什么 C# 4.0 的协变/逆变仅限于参数化接口(interface)和委托(delegate)类型?

c# - FCallAdd 优化

.net - CLR 异常系统中的故障子句是什么?