简体   繁体   English

静态类内存分配 C#

[英]Static class memory allocation where it is stored C#

I read an article which confused me about memory allocation, which stated:我读了一篇让我对内存分配感到困惑的文章,其中指出:

Singleton objects are stored on the heap while static classes are stored on the stack.单例对象存储在堆上,而静态类存储在堆栈上。

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

But in some Stackoverflow questions, such as但是在一些 Stackoverflow 问题中,例如

How is memory allocated for a static variable? 如何为静态变量分配内存?

It was described like它被描述为

Static variables are stored on the heap, regardless of whether they are declared as a reference type or a value type.静态变量存储在堆上,无论它们是声明为引用类型还是值类型。 There is only one slot in total no matter how many instances are created.无论创建多少个实例,总共只有一个槽位。

So I am confused with stack or heap storage for static classes.所以我对静态类的堆栈或堆存储感到困惑。 How is memory allocated for a static class and why?如何为静态类分配内存,为什么? How is memory allocated for singleton class?如何为单例类分配内存?

There are four possible root types in .NET Framework: .NET Framework 中有四种可能的根类型:

  • Stack references : references to local objects .堆栈引用:对本地对象的引用。 Such roots live during a method execution.这样的根存在于方法执行期间。
  • Static references : references to static objects .静态引用:对静态对象的引用。 These roots live the entire app domain life time.这些根存在于整个应用程序域生命周期中。
  • Handles : typically, these are references used for communication between managed and unmanaged code.句柄:通常,这些是用于托管和非托管代码之间通信的引用。 Such roots must live at least until the unmanaged code needs "managed" objects.这样的根必须至少存在到非托管代码需要“托管”对象为止。
  • Finalizer references : references to objects waiting to be finalized.终结器引用:对等待终结的对象的引用。 These roots live until the finalizer is run.这些根一直存在,直到终结器运行。

https://www.jetbrains.com/help/dotmemory/Analyzing_GC_Roots.html https://www.jetbrains.com/help/dotmemory/Analyzing_GC_Roots.html

High Frequency Heap高频堆

Static data and constants defined in a C# program are stored on the heap. C# 程序中定义的静态数据和常量存储在堆上。 Since they exist for the lifetime of the application, they do not need to be garbage collected and are therefore stored in a loader heap, rather than the normal Garbage Collected heap.由于它们在应用程序的整个生命周期内都存在,因此不需要进行垃圾收集,因此存储在加载程序堆中,而不是普通的垃圾收集堆中。 Specifically, static data is stored on the high-frequency heap–one of the loader heaps that exists for each AppDomain.具体来说,静态数据存储在高频堆上——每个 AppDomain 存在的加载器堆之一。

Static Data and Constants Are Stored on the Heap 静态数据和常量存储在堆上在此处输入图片说明

在此处输入图片说明

在此处输入图片说明 在此处输入图片说明

Classes will not take memory but objects do.类不会占用内存,但对象会。 The statement "static class stored in stack" sounds absurd to me.声明“存储在堆栈中的静态类”对我来说听起来很荒谬。

Classes are not stored in memory.类不存储在内存中。 When a class is loaded, their metadata may be loaded in memory and cached.当一个类被加载时,它们的元数据可能被加载到内存中并被缓存。 Apart from that classes are not stored in memory.除此之外,类不存储在内存中。

Question yourself that if static classes were stored in stack, how can you able to access it in all threads?问问自己,如果静态类存储在堆栈中,您如何能够在所有线程中访问它?

Static Variables静态变量

Static variables are an important constituent part of the MethodTable data structure.静态变量是 MethodTable 数据结构的重要组成部分。 They are allocated as a part of the MethodTable right after the method table slot array.它们在方法表槽数组之后被分配为 MethodTable 的一部分。 All the primitive static types are inlined while the static value objects like structs and reference types are referred through OBJECTREFs created in the handle tables.所有原始静态类型都是内联的,而静态值对象(如结构和引用类型)通过句柄表中创建的 OBJECTREF 引用。 OBJECTREF in the MethodTable refers to OBJECTREF in the AppDomain handle table, which refers to the heap-created object instance . MethodTable中的OBJECTREF指的是AppDomain句柄表中的OBJECTREF,指的是堆创建的对象实例 Once created, OBJECTREF in the handle table will keep the object instance on the heap alive until the AppDomain is unloaded创建后,句柄表中的 OBJECTREF 将使堆上的对象实例保持活动状态,直到卸载 AppDomain

Refer this article for more info请参阅这篇文章了解更多信息

Please stop reading that blog post or any blog posts from that author.请停止阅读该博文或该作者的任何博文。 It is utterly absurd.这是完全荒谬的。

Nice explained by Sriram Sakthivel.尼斯解释由 Sriram Sakthivel。 Basically the Heap memory is divided into 2 major parts.基本上堆内存分为两个主要部分。 Object heap memory and Loader heap memory.对象堆内存和加载程序堆内存。 As per my understanding All non static reference type are stored on object heap and all the static object(may be it is reference type or value type) are stored in loader heap.根据我的理解,所有非静态引用类型都存储在对象堆中,所有静态对象(可能是引用类型或值类型)都存储在加载程序堆中。 Gc never work on loader heap thats why they initilized only once and remain in memory throught the application. Gc 永远不会在加载程序堆上工作,这就是为什么它们只初始化一次并通过应用程序保留在内存中的原因。

Static variable goes to the special reason within Heap.It is called High Frequency Heap , all the static variables go to the High Frequency Heap in memory.静态变量去Heap内部的特殊原因。它被称为高频堆,所有的静态变量去内存中的高频堆 Objects in High Frequency Heap is not garbage collected by GC and hence static variables available throughout life time of an application.高频堆中的对象不是由 GC 垃圾收集的,因此在应用程序的整个生命周期中都可以使用静态变量。

We need to explicitly de-allocate it then we have to set it to null so that GC can clear it's allocated memory.我们需要明确地取消分配它然后我们必须将它设置为null以便 GC 可以清除它分配的内存。

Instance is created through new keyword and reside in heap that will be garbage collected if no one point it.实例通过 new 关键字创建并驻留在堆中,如果没有人指出它将被垃圾收集。 but in case of static class static constructor invoke only one to initialize memory of all static member that will reside in global memory location that is other than stack and static member remains live unless application is running.it is not garbage collected.但在静态类静态构造函数的情况下,只调用一个来初始化所有静态成员的内存,这些静态成员将驻留在堆栈以外的全局内存位置,除非应用程序正在运行,否则静态成员将保持活动状态。它不会被垃圾收集。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM