C# 静态类内存分配,存储在C中#

C# 静态类内存分配,存储在C中#,c#,memory-management,C#,Memory Management,我读了一篇关于内存分配的文章,文章中说: 单例对象存储在堆上,而静态类存储在堆上 存储在堆栈上。 链接是: 但是在一些问题上,比如 它被描述成 静态变量存储在堆上,而不管它们是声明为引用类型还是值类型。只有一个 无论创建了多少个实例,总槽数均为。 因此,我对静态类的堆栈或堆存储感到困惑。如何为静态类分配内存?为什么?如何为单例类分配内存?类不占用内存,但对象占用内存。“静态类存储在堆栈中”这句话听起来很荒谬 类不存储在内存中。加载类时,可以将其元数据加载到内存中并缓存。除此之外,类不存储在内存

我读了一篇关于内存分配的文章,文章中说:

单例对象存储在堆上,而静态类存储在堆上 存储在堆栈上。

链接是:

但是在一些问题上,比如

它被描述成

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


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

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

类不存储在内存中。加载类时,可以将其元数据加载到内存中并缓存。除此之外,类不存储在内存中

问问你们自己,若静态类存储在堆栈中,你们怎么能在所有线程中访问它

静态变量

静态变量是MethodTable的重要组成部分 数据结构。它们作为MethodTable权限的一部分进行分配 在方法表插槽数组之后。所有基本静态类型都是 内联,而静态值对象,如结构和引用 类型通过句柄表中创建的ObjectRef引用。 MethodTable中的OBJECTREF引用AppDomain中的OBJECTREF 句柄表,引用堆创建的对象实例。一旦 创建时,句柄表中的OBJECTREF将保留对象实例 在卸载AppDomain之前,在堆上保持活动状态

提及


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

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

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


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

在.NET Framework中有四种可能的根类型:

  • 堆栈引用:对本地对象的引用。这样的根在方法执行期间存在
  • 静态引用:对静态对象的引用。这些根在整个应用程序域生命周期中都存在
  • 句柄:通常,这些句柄是用于托管代码和非托管代码之间通信的引用。这样的根必须至少存在到非托管代码需要“托管”对象为止
  • 终结器引用:对等待终结的对象的引用。这些根在运行终结器之前一直有效

高频堆

静态数据和C#程序中定义的常量存储在堆中。由于它们在应用程序的生命周期内存在,因此不需要对它们进行垃圾收集,因此它们存储在加载程序堆中,而不是普通的垃圾收集堆中。具体来说,静态数据存储在高频堆上——每个AppDomain都存在的加载程序堆之一


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

类不会占用内存,但对象会占用内存。在我看来,堆栈中存储的static class语句听起来很荒谬。@sriram是的。静态变量呢?@SivaRajini静态变量存储在堆的某个地方。如果使用类的实例,它将存储在堆中,但堆中有一些区域可以存储静态变量和非静态变量。我认为可能是,静态类有内存。请阅读我的答案,如果我错了请更正me@SurenSrapyan静态类不存储在任何位置。但是静态字段是存储的。它存储在某个特殊位置的堆中。要知道特殊位置是什么,请阅读我回答中的blockquote部分。使用
new
关键字创建的实例没有任何特殊之处。而且也不能保证会在堆上创建任何对象。我当然可以写
intx=newint()