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# 中静态结构存储在哪里? 的相关文章

  • 扫描文本文件时如何跳过行?

    我想扫描一个文件并在阅读之前跳过一行文本 我试过 fscanf pointer n struct test i j 但这个语法只是从第一行开始 我可以使用 scanf 使用以下指令跳过行 fscanf config file n n 格式字
  • 更快的算法来计算有多少数字可以被范围内的特定整数整除

    int a b c d 0 cin gt gt a gt gt b gt gt c for int i a i lt b i if i c 0 d cout lt
  • 如何将pdf页面设置设置为打印属性对话框?

    大家好 我想知道如何设置 pdf 页面设置到打印属性对话框 例如 如果我的 PDF 页面设置为横向 则布局会自动显示横向而不是纵向 如果我的 PDF 页面设置为纵向 则布局会自动显示纵向 我在这个主题上做了很多研发 但没有找到任何满意的链接
  • 返回 int& 的函数[重复]

    这个问题在这里已经有答案了 我在网上查了一下发现一篇试图解释的文章std move和右值 http thbecker net articles rvalue references section 01 html并发现了一些我实在无法掌握的东
  • 为什么假设 send 可能返回的数据少于在阻塞套接字上传输的请求数据?

    在流套接字上发送数据的标准方法始终是调用 send 并写入一大块数据 检查返回值以查看是否发送了所有数据 然后再次调用 send 直到整个消息被接受 例如 这是一个常见方案的简单示例 int send all int sock unsign
  • rand() 播种与 time() 问题

    我很难弄清楚如何使用 rand 并使用 Xcode 用 time 为其播种 我想生成 0 到 1 之间的随机十进制数 该代码为我提供了元素 1 和 2 看似随机的数字 但元素 0 始终在 0 077 左右 有什么想法吗 我的代码是 incl
  • 将成员函数作为参数传递/c++

    我想用 C 实现一个类b可以通过封装该迭代器类型的成员集进行某种迭代 喜欢 b object for each x do function f so 函数 f会得到每个人的x成员并做任何事情 比方说 void function f x me
  • 抽象类或接口。哪种方式是正确的?

    有两种方法可以选择抽象类或接口 微软解决方案和Oracle解决方案 微软 设计指南 请使用抽象 在 Visual Basic 中为 MustInherit 类而不是接口来将协定与实现分离 http msdn microsoft com en
  • 数据损坏 C++ 和 Python 之间的管道

    我正在编写一些代码 从 Python 获取二进制数据 将其通过管道传输到 C 对数据进行一些处理 在本例中计算互信息度量 然后将结果通过管道传输回 Python 在测试时 我发现如果我发送的数据是一组尺寸小于 1500 X 1500 的 2
  • 如何在 C# 中使用 XmlDsigC14NTransform 类

    我正在尝试使用规范化 xml 节点System Security Cryptography Xml XMLDsigC14nTransformC net Framework 2 0 的类 该实例需要三种不同的输入类型 NodeList Str
  • 如何将字符串转换为 Indian Money 格式?

    我正在尝试将字符串转换为印度货币格式 例如如果输入为 1234567 则输出应为 12 34 567 我编写了以下代码 但它没有给出预期的输出 CultureInfo hindi new CultureInfo hi IN string t
  • 如何在 VS Code 中为 CMake 项目设置 C/C++ IntelliSense?

    我正在尝试使用 libTooling 编写一个工具 我对其进行了设置 以便它可以使用 LLVM 文档中的示例进行编译 然而 C C IntelliSense 似乎不适用于 CMake 项目 我的工具位于
  • C++ 标准中短语“构造函数没有名称”的含义

    在尝试理解 C 标准中的 构造函数没有名称 这句话时 我似乎在 clang 中发现了一个错误 有人可以证实这一点吗 VS2015 and gcc rejects this code and I think they it are is co
  • 微软语音识别速度

    我正在使用微软的语音识别器开发一个小型练习应用程序 对于我正在做的事情来说 我似乎无法让它足够快地识别单个单词 我希望能够正常说话 系统将从我所说的内容中抓取 关键字 并生成一个字符串 目前我正在使用 5 个单词的自定义语法 红 蓝 黄 绿
  • 为什么C语言中可以使用多个分号?

    在 C 中我可以执行以下操作 int main printf HELLO WORLD 它有效 这是为什么 我个人的想法 分号是一个 NO OPERATION 来自维基百科 指示符 拥有一大串分号与拥有一个分号并告诉 C 语句已结束具有相同的
  • 将一个 long 转换为两个 int 以进行重构

    我需要将一个参数作为两个 int 参数传递给 Telerik Report 因为它不能接受长参数 将 long 拆分为两个 int 并在不丢失数据的情况下重建它的最简单方法是什么 使用掩蔽和移位是最好的选择 根据文档 long 保证为 64
  • 程序退出后,TcpListener Socket 仍处于活动状态

    当我的程序退出时 我试图停止 TCP 侦听器 我不关心套接字或任何活动客户端套接字上当前活动的任何数据 套接字清理代码本质上是 try myServer Server Shutdown SocketShutdown Both catch E
  • 在何处将 CFLAG(例如 -std=gnu99)添加到 (Eclipse CDT) 自动工具项目中

    我有一个简单的 Autotools C 项目 不是 C 其框架是由 Eclipse CDT Juno 为我创建的 CFLAG 通过检查 似乎是 g O2 我希望所有生成的 make 文件也具有 std gnu99附加到 CFLAG 因为我使
  • 通过 cmake 链接作为外部项目包含的 opencv 库[重复]

    这个问题在这里已经有答案了 我对 cmake 比较陌生 经过几天的努力无法弄清楚以下事情 我有一个依赖于 opencv 的项目 它本身就是一个 cmake 项目 我想静态链接 opencv 库 我正在做的是我的项目中有一份 opencv 源
  • 使用剪贴板 SetText 换行

    如何使用 SetText 方法添加换行符 I tried Clipboard SetText eee n xxxx 但当我将剪贴板数据粘贴到记事本中时 它没有给我预期的结果 预期结果 eee xxxx 我怎样才能做到这一点 Windows

随机推荐

  • 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我明白 结构可以在堆栈或寄存器中