存储C#的静态类内存分配

本文关键字:内存 分配 静态类 存储 | 更新日期: 2023-09-27 18:20:44

我读到一篇文章,它让我对内存分配感到困惑,其中写道:

Singleton对象存储在堆上,而静态类存储在堆栈上

链接是:http://www.dotnetjalps.com/2013/06/Static-vs-Singleton-in-Csharp-Difference-between-Singleton-and-Static.html

但在一些堆栈溢出问题中,例如

如何为静态变量分配内存?

它被描述为

静态变量存储在堆中,无论它们是声明为引用类型还是值类型。只有一个插槽,无论创建了多少个实例

因此,我对静态类的堆栈或堆存储感到困惑。如何为静态类分配内存,为什么?如何为singleton类分配内存?

存储C#的静态类内存分配

类不会占用内存,但对象会占用内存。"静态类存储在堆栈中"这句话听起来很荒谬。

类不存储在内存中。当一个类被加载时,它们的元数据可能被加载到内存中并被缓存。除此之外,类不存储在内存中。

问问自己,如果静态类存储在堆栈中,您如何能够在所有线程中访问它?

静态变量

静态变量是MethodTable的重要组成部分数据结构。它们被分配为MethodTable权限的一部分在方法表槽数组之后。所有基元静态类型都是内联,而静态值对象(如structs和reference)类型是通过句柄表中创建的OBJECTREF来引用的。MethodTable中的OBJECTREF引用AppDomain中的OBECTREF句柄表,,它引用堆创建的对象实例。一旦创建时,句柄表中的OBJECTREF将保留对象实例在堆上处于活动状态,直到AppDomain卸载

请参阅本文了解更多信息

请停止阅读该博客文章或该作者的任何博客文章。这完全是荒谬的。

斯里拉姆·萨克西维尔解释得很好。堆内存基本上分为两个主要部分。对象堆内存和Loader堆内存。根据我的理解,所有非静态引用类型都存储在对象堆中,所有静态对象(可能是引用类型或值类型)都存储在加载器堆中。Gc从不在加载器堆上工作,这就是为什么它们只初始化一次,并通过应用程序保留在内存中。

静态变量进入堆中的特殊原因。它被称为高频堆,所有静态变量都进入内存中的低频堆频堆中的对象不是GC垃圾收集的,因此静态变量在应用程序的整个生命周期内都可用。

我们需要显式地取消分配它,然后我们必须将它设置为null,以便GC可以清除它分配的内存。

实例是通过new关键字创建的,并且驻留在堆中,如果没有人指向它,就会被垃圾收集。但在静态类的情况下,静态构造函数只调用一个来初始化所有静态成员的内存,这些成员将驻留在堆栈以外的全局内存位置,并且静态成员保持活动状态,除非应用程序正在运行。它不是垃圾收集的。