C# 中静态结构存储在哪里?

2024-02-18

From 这个问题 https://stackoverflow.com/questions/2565331/fields-of-class-are-they-stored-in-the-stack-or-heap我明白

  • 结构可以在堆栈或寄存器中分配,但不能在堆上分配
  • 如果结构体是堆上引用类型对象的一部分,则该结构体也将位于堆上

但是,如果结构不是对象的一部分,而是类的静态成员,如下所示:

public class Program
{
    public static CustomStructType inst1;
    
    static void Main(string[] args)
    {
        //assigning an instance of value type to the field
        inst1 = new CustomStructType();
    }
}

public struct CustomStructType
{
    //body
}

不会有这样的例子Program在堆上。那么结构体将存储在哪里呢?

This question is a rephrased version of this deleted question https://stackoverflow.com/questions/67755574/after-looking-into-the-following-sof-post-is-my-assumption-correct. The user was deleted, so the question and answer went with it. I still found the idea interesting and the debugging result even more, so I chose to repeat it here.

关于潜在的重复项:

  • 这个问题 https://stackoverflow.com/questions/2565331/fields-of-class-are-they-stored-in-the-stack-or-heap创建类的实例。如前所述,我知道作为对象一部分存储的结构位于堆上。我的代码没有创建类的实例。
  • 这个问题 https://stackoverflow.com/a/24376073/480982无论它是否是静态的,都将其保持打开状态,答案是“不,如果您在 Main 内部执行此操作,一般来说,它不会在堆上分配。”
  • 这个问题 https://stackoverflow.com/questions/203695/does-using-new-on-a-struct-allocate-it-on-the-heap-or-stack乔恩·斯基特(Jon Skeet)有一个很好的答案,它说每个new在堆栈上分配空间。

也许你错过了:埃里克·利珀特(Eric Lippert)在旁注中提到了这一点:

[...] 和静态变量存储在堆上。

这是在上下文中写的

事实是,这是一个实施细节 [...]

Microsoft 的实现方式如下:

但为什么静态变量要存储在堆上呢?

好吧,即使是 Main() 方法也不会永远存在。 Main() 方法可能会结束,而其他一些线程可能仍在运行。在这种情况下,结构会发生什么?它不一定位于堆上,但我希望您看到它不能位于堆栈上而不是位于寄存器中。该结构必须位于其他线程仍然能够访问它的某个位置。堆是一个不错的选择。

Main() 终止的代码示例:

using System;
using System.Threading;

public class Program
{
    public static CustomStructType inst1;

    static void Main(string[] args)
    {
        new Thread(AccessStatic).Start();
        //assigning an instance of value type to the field
        inst1 = new CustomStructType();
        Console.WriteLine("Main is gone!");
    }

    static void AccessStatic()
    {
        Thread.Sleep(1000);
        Console.WriteLine(inst1);
        Console.ReadLine();
    }
}

public struct CustomStructType
{
    //body
}

让我们回到原来的代码。如有疑问,您可以随时使用调试器进行检查。这是 .NET Framework 4.8 (4.8.4341.0) 中发布版本的调试会话。

我正在调试WinDbg 预览 https://www.microsoft.com/en-us/p/windbg-preview/9pgjgd53tn86?activetab=pivot:overviewtab,这是微软提供的免费调试器。不过使用起来并不方便。我是从书上了解到的“高级 .NET 调试”作者:Mario Hewardt https://rads.stackoverflow.com/amzn/click/com/B002YYWEKE.

我插入了一个Console.ReadLine()为了简单起见,我不需要逐步完成所有内容并在正确的时间停止。

加载.NET扩展

ntdll!DbgBreakPoint:
77534d10 cc              int     3
0:006> .loadby sos clr

搜索一个实例Program(只是为了检查问题的前提是否正确)确实给出了 0 个对象:

0:007> !dumpheap -type Program
 Address       MT     Size

Statistics:
      MT    Count    TotalSize Class Name
Total 0 objects

搜索班级:

0:006> !name2ee *!Program
Module:      787b1000
Assembly:    mscorlib.dll
--------------------------------------
Module:      01724044
Assembly:    StructOnHeap.exe
Token:       02000002
MethodTable: 01724dcc
EEClass:     01721298            <--- we need this
Name:        Program

获取有关班级的信息:

0:006> !dumpclass 01721298
Class Name:      Program
mdToken:         02000002
File:            C:\...\bin\Release\StructOnHeap.exe
Parent Class:    787b15c8
Module:          01724044
Method Table:    01724dcc
Vtable Slots:    4
Total Method Slots:  5
Class Attributes:    100001  
Transparency:        Critical
NumInstanceFields:   0
NumStaticFields:     1
      MT    Field   Offset                 Type VT     Attr    Value Name
01724d88  4000001        4     CustomStructType  1   static 0431357c inst1
                                                            ^-- now this

检查垃圾收集堆在哪里:

0:006> !eeheap -gc
Number of GC Heaps: 1
generation 0 starts at 0x03311018
generation 1 starts at 0x0331100c
generation 2 starts at 0x03311000
ephemeral segment allocation context: none
 segment     begin  allocated      size
03310000  03311000  03315ff4  0x4ff4(20468)
Large object heap starts at 0x04311000
 segment     begin  allocated      size
04310000  04311000  04315558  0x4558(17752)             <-- look here
Total Size:              Size: 0x954c (38220) bytes.
------------------------------
GC Heap Size:    Size: 0x954c (38220) bytes.

是的,它位于从 0x04311000 开始的大对象堆上。

顺便说一句:令我惊讶的是,如此小的“对象”(结构)将分配在大对象堆上。通常,LOH 将仅包含 85000+ 字节的对象。但这是有道理的,因为 LOH 通常不会被垃圾收集,而且您也不需要垃圾收集static items.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C# 中静态结构存储在哪里? 的相关文章

  • 将字节数组转换为托管结构

    更新 这个问题的答案帮助我编写了开源项目GitHub 上的 AlicanC 现代战争 2 工具 https github com AlicanC AlicanC s Modern Warfare 2 Tool 你可以看到我是如何阅读这些数据
  • 从多线程程序中调用 system()

    我们正在开发一个用 C 编写的多线程内存消耗应用程序 我们必须执行大量的 shellscript linux 命令 并获取返回码 读完之后article http www linuxprogrammingblog com threads a
  • 为什么Apache MPM prefork.c 使用互斥体来保护accept()?

    我坐下来读书Apache 的 MPM prefork c http code metager de source xref apache httpd server mpm prefork prefork c这段代码使用了一个名为accept
  • SSL/TLS/HTTPS 站点在 C#/.NET WebBrowser 控件中非常慢,但在 Internet Explorer 中则很好

    背景 我正在修改自动维基浏览器 http en wikipedia org wiki Wikipedia AutoWikiBrowser使用托管在安全服务器上的 MediaWiki 站点 我允许用户通过 C 应用程序中的 WebBrowse
  • (const T v) 在 C 中从来都不是必需的,对吗?

    例如 void func const int i 在这里 const是不必要的 因为所有参数都是按值传递的 包括指针 真的吗 C 中的所有参数确实都是按值传递 这意味着无论您是否包含该参数 实际参数都不会改变const or not 然而
  • CultureInfo 的实例(来自相同的文化)根据操作系统而变化

    我有一个网站 上面写着这样的日期 CultureInfo cultureInfo CultureInfo GetCultures CultureTypes AllCultures FirstOrDefault c gt string Equ
  • 在 C# Winforms 应用程序中嵌入 Windows XP 主题

    我有一个旧版 C Windows 窗体应用程序 其布局是根据 Windows XP 默认主题设计的 由于需要将其作为 Citrix 应用程序进行分发 该应用程序现在看起来像经典主题应用程序 因为 Citrix 不鼓励使用主题系统服务 所以
  • 获取尚未实例化的类的函数句柄

    我对 C 相当陌生 我想做的事情可能看起来很复杂 首先 我想获取一些函数的句柄以便稍后执行它们 我知道我可以通过以下方式实现这一目标 List
  • 将字符串转换为正确的 URI 格式?

    有没有简单的方法可以将电子邮件地址字符串转换为正确的 URI 格式 Input http mywebsite com validate email 3DE4ED727750215D957F8A1E4B117C38E7250C33 email
  • TcpClient 在异步读取期间断开连接

    我有几个关于完成 tcp 连接的问题 客户端使用 Tcp 连接到我的服务器 在接受客户端后listener BeginAcceptTcpClient ConnectionEstabilishedCallback null 我开始阅读netw
  • 从 Code::Blocks 运行程序时出现空白控制台窗口 [重复]

    这个问题在这里已经有答案了 当我尝试在 Code Blocks 中构建并运行新程序时 控制台窗口弹出空白 我必须单击退出按钮才能停止它 它对我尝试过的任何新项目 包括 Hello world 都执行此操作 奇怪的是 它对于我拥有的任何旧项目
  • OpenCV 2.4.3 中的阴影去除

    我正在使用 OpenCV 2 4 3 最新版本 使用内置的视频流检测前景GMG http docs opencv org modules gpu doc video html highlight gmg gpu 3a 3aGMG GPU算法
  • 如何随着分辨率的变化自动调整大小和调整表单控件

    我注意到某些应用程序会更改控件的位置以尽可能适应当前的分辨率 例如 如果窗口最大化 则控件的设置方式应使整个 GUI 看起来平衡 是否可以使用 C 在 Visual studio 2010 中制作或实现此功能 Use Dock http m
  • 从 R 到 C 处理列表并访问它

    我想使用从 R 获得的 C 列表 我意识到这个问题与此非常相似 使用 call 在 R 和 C 之间传递数据帧 https stackoverflow com questions 6658168 passing a data frame f
  • asp.net网格分页的SQL查询

    我在用iBatis and SQLServer 使用偏移量和限制进行分页查询的最佳方法是什么 也许我添加该列ROW NUMBER OVER ORDER BY Id AS RowNum 但这只会阻止简单查询的数据访问 在某些情况下 我使用选择
  • 0-1背包算法

    以下 0 1 背包问题是否可解 浮动 正值和 浮动 权重 可以是正数或负数 背包的 浮动 容量 gt 0 我平均有 这是一个相对简单的二进制程序 我建议用蛮力进行修剪 如果任何时候你超过了允许的重量 你不需要尝试其他物品的组合 你可以丢弃整
  • C 中带有指针的结构的内存开销[重复]

    这个问题在这里已经有答案了 我意识到当我的结构包含指针时 它们会产生内存开销 这里有一个例子 typedef struct int num1 int num2 myStruct1 typedef struct int p int num2
  • 为什么 Linux 对目录使用 getdents() 而不是 read()?

    我浏览 K R C 时注意到 为了读取目录中的条目 他们使用了 while read dp gt fd char dirbuf sizeof dirbuf sizeof dirbuf code Where dirbuf是系统特定的目录结构
  • C++、三元运算符、std::cout

    如何使用 C 用三元运算符编写以下条件 int condition1 condition2 condition3 int double result int or double std cout lt lt condition1 resul
  • 在 Xamarin 中获取 OutOfMemoryException

    java lang OutOfMemoryError 考虑增加 JavaMaximumHeapSize Java 执行时内存不足 java exe 我的 Visualstudio Xamarin 项目出现内存不足异常 请帮助我如何解决此问题

随机推荐

  • a[:] = b 和 a = b[:] 之间的区别? (Python)

    我被要求进行编码测试 但不知道答案 有人有主意吗 是切片运算符 当它位于左侧时 它会覆盖列表的内容而不创建新的引用 当它位于右侧时 它会创建具有相同内容的列表的副本
  • 如何使非英语网址在 next.js 中工作?

    如何使非英语 URL 与 next js ssr client 一起使用 欢迎任何想法 重写等 前段时间重写有助于解决这个问题 但在一些更新之后它停止工作 这是我的尝试fix this https github com zeit next
  • 从 listView 中删除标题

    我在尝试从文件中删除标头时遇到一些问题listView 起初我使用addHeaderView 添加它 但是当我更改为另一个布局时我希望它消失但是removeHeaderView 不起作用 我也尝试将可见性设置为 消失 但它并没有消失 我能做
  • RadioGroup 扩展relativelayout?

    我正在尝试为我的应用程序制作一个单选按钮网格 据我所知 使用常规方法这是不可能的RadioGroup因为它扩展了 LinearLayout 并且如果你尝试安排RadioButtons在里面使用RelativeLayoutRadioGroup
  • Prolog家族关系,意外失败

    谁能告诉我为什么我的姨妈关系不工作 每当我尝试调用它时它都会返回 false 我在下面写的叔叔关系似乎运作得很好 我不明白有什么区别 我也尝试过 not mother X Y 最后也但这并没有改变任何东西 FACTS parents dav
  • 使用泛型类型参数作为参数

    我正在尝试创建一个通用函数 它用一个函数调用另一个函数any类型参数 这是我尝试过的 static GetInstance
  • 为什么 CROSS APPLY *不*在此查询中出现无效列错误?

    我正在编写一些代码来查询一些DMV 某些列可能存在于 DMV 中 也可能不存在 具体取决于 SQL 版本 我在网上发现了一个有趣的建议 如何使用跳过特定检查CROSS APPLY 下面的查询是读取 DMV 中可能缺失的列的代码示例 该代码为
  • 在 JavaScript 中交换两个对象

    我有以下代码 MyObject prototype doIt function var a this obj1 var b this obj2 我怎样才能交换的值这个 obj1 and 这个 obj2所以obj1变成obj2 obj2变成o
  • 模板、函数指针和 C++0x

    我的个人实验之一是为了了解 C 0x 的一些功能 我试图将函数指针传递给要执行的模板函数 最终执行应该发生在不同的线程中 但对于所有不同类型的功能 我无法使模板正常工作 include
  • 类型错误:$scope.apply 不是函数

    我试图在检索联系人列表后呈现它rdflib js 它正在正确加载并将其保存在范围内的列表中 但我无法渲染 scope 不更新的正弦 看起来我正在调用 scope apply 在错误的地方 发生错误是因为我将其称为外部角度 但我故意在角度上下
  • 返回 pandas 数据帧的函数

    我不清楚我的问题 所以我正在审查这个问题 我有一个操作通用数据框的函数 它删除并重命名列和记录 def manipulate df df local df local rename columns A grouping column inp
  • 如何为复杂的数学方程创建 Java GUI 程序

    我正在学习 Java AWT 和 Swings 并了解如何创建基本的 GUI 元素 并且我能够使用它来编写一些程序 但是 当我试图了解如何为一些复杂的数学方程创建图表时 我无法找到一些文档或任何示例 例如 在这篇文章中 如何求解三角方程co
  • 获取我的主屏幕小部件的大小

    我只想知道我当前的小部件有多大 我发现了很多设置最小尺寸的问题 但我不想设置它 相反 我想显示适合小部件的信息 如果小部件太小 我需要隐藏一些东西 但我需要知道它的大小 我阅读了一些类的源代码 例如AppWidgetProvider 甚至文
  • Go SDK Apache Beam:单例侧输入 Singleton for int 定义不明确

    使用适用于 Apache Beam 的 Go SDK 我尝试使用侧面输入创建 PCollection 的视图 但我收到这个奇怪的错误 Failed to execute job on ctx making side input 0 sing
  • 查找两个顶点之间的所有最短路径

    给定一个有向图G V E 两个顶点s t和两个权重函数w1 w2 我需要找到最短路径s to t by w2在所有最短路径之间s to t by w1 首先 我怎样才能找到两个顶点之间的所有最短路径s and t Dijkstra 算法帮助
  • Webpack DefinePlugin 未设置/读取 node_env 变量

    我在通过 Webpack 的 DefinePlugin 将 node env var 注入到我的代码中时遇到了真正的问题 并且在阅读了大量帖子后似乎没有任何效果 我有一种感觉 我错过了什么 所以我的生产 webpack 配置是 Config
  • 在 r 和正则表达式中,如何检测排除某些混合条件的字符

    我试图检测字符串中的一些点 并将它们替换为单词旁边的相同点 例如 变为 AAA 但有一些条件我想避免替换 如果点之前有一个空格和一个字符 如果点位于两个连字符 之间 例如 如果输入是 string lt first second third
  • IntegrityError:“user_id”列中的空值违反了非空约束(Django Rest Framework)

    我是 Django Rest Framework 的新手 我收到一个完整性错误 我正在尝试解决该错误 Intro 我有 2 个型号Patient and Embryo Patient 是 Django 默认用户的外键 只有 1 位用户是超级
  • 在开关内使用枚举

    我们可以在开关内使用枚举吗 public enum Color RED BLUE YELLOW public class Use Color c Color BLUE public void test switch c case Color
  • C# 中静态结构存储在哪里?

    From 这个问题 https stackoverflow com questions 2565331 fields of class are they stored in the stack or heap我明白 结构可以在堆栈或寄存器中