Is there an advanced article which I can read that can explain how memory is allocated for different types (value and reference) in .net framework.
是否有一篇我可以阅读的高级文章可以解释如何在.net框架中为不同类型(值和引用)分配内存。
for example we know that value types are allocated space on a stack, but how is that managed?
例如,我们知道值类型是在堆栈上分配空间,但是如何管理?
Also how are reference types managed in a heap and where are the actual values stored. (Reference type like any Class will contain many value types, where are they saved and how are they managed)
如何在堆中管理引用类型以及存储实际值的位置。 (像任何类一样的引用类型将包含许多值类型,它们保存在哪里以及如何管理它们)
5 个解决方案
#1
It's more complicated than you might think. Even your claim that "value types are allocated on the stack" isn't correct. For example:
这比你想象的要复杂得多。甚至你声称“值类型在堆栈上分配”也是不正确的。例如:
class Foo
{
int x;
}
int
is a value type, but the value for x will always be on the heap because it will be stored with the rest of the data for the instance of Foo which is a class.
int是一个值类型,但x的值总是在堆上,因为它将与Foo实例的其余数据一起存储,这是一个类。
Additionally, captured variables for anonymous functions and iterator blocks make life trickier.
此外,匿名函数和迭代器块的捕获变量使生活变得更加棘手。
I have an article about C# heap/stack memory you may find useful, but you might also want to read Eric Lippert's blog post on "The stack is an implementation detail". In particular, a future C# compiler could decide to store all of its local variables on the heap, using the stack just to hold a reference to an instance created at the start of the method... that wouldn't defy the C# spec at all.
我有一篇关于C#堆/堆内存的文章,你可能会觉得有用,但你可能还想阅读Eric Lippert关于“堆栈是一个实现细节”的博客文章。特别是,未来的C#编译器可以决定将所有局部变量存储在堆上,使用堆栈只是为了保存对在方法开始时创建的实例的引用...这不会违反C#规范所有。
#2
A value type is "allocated" where it is defined.
值类型在已定义的位置“已分配”。
What that means depends on where you define it:
这意味着什么取决于你定义它的位置:
- In a class/struct, as a field in that struct, enlarging the class/struct in memory to fit the value type value in there
- As a local variable in a method, on the stack, or as a register, or as a field in a generated class (when using "closures"), depending on optimizations
- As a parameter to a method, on the stack or as a register, depending on optimizations
在类/结构中,作为该结构中的字段,在内存中放大类/结构以适合其中的值类型值
作为方法中的局部变量,在堆栈上,或作为寄存器,或作为生成的类中的字段(当使用“闭包”时),取决于优化
作为方法的参数,在堆栈上或作为寄存器,取决于优化
A reference type is sort of a dual value. A reference type is at heart a pointer, and the pointer value follows the same rules for "allocation" as a value type, but once you store a value in it, ie. a reference to an object, that object is on the heap somewhere else.
引用类型是双重值。引用类型的核心是指针,指针值遵循与“分配”相同的规则作为值类型,但是一旦在其中存储了值,即。对象的引用,该对象在其他地方的堆上。
In other words, the reference variable itself is "allocated" as a value type, but the object it refers to is on the heap.
换句话说,引用变量本身被“分配”为值类型,但它引用的对象在堆上。
When you construct an object from a class, space is allocated on the heap to fit all the fields of that class + some overhead in that space.
当您从类构造对象时,会在堆上分配空间以适合该类的所有字段+该空间中的一些开销。
I seem to recall Jon Skeet having an article about the subject, I'm sure he'll jump in with an answer really soon so stay tuned.
我似乎记得Jon Skeet有一篇关于这个主题的文章,我相信他很快就能得到答案所以请继续关注。
#3
This article seems advanced without going overboard. It should provide you with a much better understanding:
这篇文章看起来很先进而不会过分。它应该为您提供更好的理解:
http://www.simple-talk.com/dotnet/.net-framework/understanding-garbage-collection-in-.net/
#4
Remember the rule, Reference types always goes to the Heap, whereas Value Types always go where they were declared. If a Value Type is declared outside of a method, but inside a Reference Type it will be placed within the Reference Type on the Heap.
记住规则,引用类型总是转到堆,而值类型总是转到它们声明的位置。如果在方法之外声明值类型,但在引用类型内,它将被放置在堆上的引用类型中。
#5
When a method is called the amount of space required by value types is known in advance (it can be computed by the compiler). This space is allocated on the stack and is only available for the duration of the method call. For each new method call the memory used on the stack grows and when the method exits it shrinks back to it's previous level.
调用方法时,值类型所需的空间量是预先知道的(可以由编译器计算)。此空间在堆栈上分配,仅在方法调用期间可用。对于每个新方法调用,堆栈上使用的内存都会增长,当方法退出时,它会收缩回到之前的级别。
Reference types are allocated on the heap. The heap is basically a block of memory used for that purpose. An object stored on the heap is primarily the fields of the object stored in the the memory allocated to the object. Thus value type fields are stored "inside" the object on the heap. Reference type fields are stored as a reference (or pointer) to the referenced object. The memory on the heap are managed by garbage collection. It is a complex subject but the short story is that memory allocated to unused objects on the heap are freed and thus eligble for reuse at regular intervals by the garbage collector.
引用类型在堆上分配。堆基本上是用于此目的的内存块。存储在堆上的对象主要是存储在分配给对象的内存中的对象的字段。因此,值类型字段存储在堆上的对象“内部”。引用类型字段存储为引用对象的引用(或指针)。堆上的内存由垃圾回收管理。这是一个复杂的主题,但简短的故事是分配给堆上未使用的对象的内存被释放,因此可以由垃圾收集器定期重复使用。
#1
It's more complicated than you might think. Even your claim that "value types are allocated on the stack" isn't correct. For example:
这比你想象的要复杂得多。甚至你声称“值类型在堆栈上分配”也是不正确的。例如:
class Foo
{
int x;
}
int
is a value type, but the value for x will always be on the heap because it will be stored with the rest of the data for the instance of Foo which is a class.
int是一个值类型,但x的值总是在堆上,因为它将与Foo实例的其余数据一起存储,这是一个类。
Additionally, captured variables for anonymous functions and iterator blocks make life trickier.
此外,匿名函数和迭代器块的捕获变量使生活变得更加棘手。
I have an article about C# heap/stack memory you may find useful, but you might also want to read Eric Lippert's blog post on "The stack is an implementation detail". In particular, a future C# compiler could decide to store all of its local variables on the heap, using the stack just to hold a reference to an instance created at the start of the method... that wouldn't defy the C# spec at all.
我有一篇关于C#堆/堆内存的文章,你可能会觉得有用,但你可能还想阅读Eric Lippert关于“堆栈是一个实现细节”的博客文章。特别是,未来的C#编译器可以决定将所有局部变量存储在堆上,使用堆栈只是为了保存对在方法开始时创建的实例的引用...这不会违反C#规范所有。
#2
A value type is "allocated" where it is defined.
值类型在已定义的位置“已分配”。
What that means depends on where you define it:
这意味着什么取决于你定义它的位置:
- In a class/struct, as a field in that struct, enlarging the class/struct in memory to fit the value type value in there
- As a local variable in a method, on the stack, or as a register, or as a field in a generated class (when using "closures"), depending on optimizations
- As a parameter to a method, on the stack or as a register, depending on optimizations
在类/结构中,作为该结构中的字段,在内存中放大类/结构以适合其中的值类型值
作为方法中的局部变量,在堆栈上,或作为寄存器,或作为生成的类中的字段(当使用“闭包”时),取决于优化
作为方法的参数,在堆栈上或作为寄存器,取决于优化
A reference type is sort of a dual value. A reference type is at heart a pointer, and the pointer value follows the same rules for "allocation" as a value type, but once you store a value in it, ie. a reference to an object, that object is on the heap somewhere else.
引用类型是双重值。引用类型的核心是指针,指针值遵循与“分配”相同的规则作为值类型,但是一旦在其中存储了值,即。对象的引用,该对象在其他地方的堆上。
In other words, the reference variable itself is "allocated" as a value type, but the object it refers to is on the heap.
换句话说,引用变量本身被“分配”为值类型,但它引用的对象在堆上。
When you construct an object from a class, space is allocated on the heap to fit all the fields of that class + some overhead in that space.
当您从类构造对象时,会在堆上分配空间以适合该类的所有字段+该空间中的一些开销。
I seem to recall Jon Skeet having an article about the subject, I'm sure he'll jump in with an answer really soon so stay tuned.
我似乎记得Jon Skeet有一篇关于这个主题的文章,我相信他很快就能得到答案所以请继续关注。
#3
This article seems advanced without going overboard. It should provide you with a much better understanding:
这篇文章看起来很先进而不会过分。它应该为您提供更好的理解:
http://www.simple-talk.com/dotnet/.net-framework/understanding-garbage-collection-in-.net/
#4
Remember the rule, Reference types always goes to the Heap, whereas Value Types always go where they were declared. If a Value Type is declared outside of a method, but inside a Reference Type it will be placed within the Reference Type on the Heap.
记住规则,引用类型总是转到堆,而值类型总是转到它们声明的位置。如果在方法之外声明值类型,但在引用类型内,它将被放置在堆上的引用类型中。
#5
When a method is called the amount of space required by value types is known in advance (it can be computed by the compiler). This space is allocated on the stack and is only available for the duration of the method call. For each new method call the memory used on the stack grows and when the method exits it shrinks back to it's previous level.
调用方法时,值类型所需的空间量是预先知道的(可以由编译器计算)。此空间在堆栈上分配,仅在方法调用期间可用。对于每个新方法调用,堆栈上使用的内存都会增长,当方法退出时,它会收缩回到之前的级别。
Reference types are allocated on the heap. The heap is basically a block of memory used for that purpose. An object stored on the heap is primarily the fields of the object stored in the the memory allocated to the object. Thus value type fields are stored "inside" the object on the heap. Reference type fields are stored as a reference (or pointer) to the referenced object. The memory on the heap are managed by garbage collection. It is a complex subject but the short story is that memory allocated to unused objects on the heap are freed and thus eligble for reuse at regular intervals by the garbage collector.
引用类型在堆上分配。堆基本上是用于此目的的内存块。存储在堆上的对象主要是存储在分配给对象的内存中的对象的字段。因此,值类型字段存储在堆上的对象“内部”。引用类型字段存储为引用对象的引用(或指针)。堆上的内存由垃圾回收管理。这是一个复杂的主题,但简短的故事是分配给堆上未使用的对象的内存被释放,因此可以由垃圾收集器定期重复使用。