我有点困惑的是,在C#中只引用类型得到垃圾收集。 这意味着GC挑选只引用类型的存储器解除分配。 所以与值类型会发生什么,因为他们也占用内存堆栈?

有帮助吗?

解决方案

一开始,无论他们是堆的堆或部分依赖于他们的一部分,什么情况下 - 如果他们是引用类型之内,他们将在堆上反正。 (你应该考虑多少你真的关心栈/堆鸿沟无论如何 - 作为埃里克利珀已经写的,它的的很大程度上实现细节。)

然而,基本上值型存储器中当所述上下文被回收回收 - 所以当堆叠通过您从方法返回弹出,即“再回收的”整个堆栈帧。同样,如果该值类型值实际上是一物体的一部分,则垃圾回收该对象当存储器被回收。

在简短的回答是,你不必对此担心:)(这是假设你没有任何的其他的比内存约,当然担心 - 如果您已得到了与那些需要释放,这是一个有些不同的场景原生手柄引用结构。)

其他提示

  

我有点困惑的是,在C#中只引用类型得到垃圾收集。

这不是事实。或者说,这句话的真假取决于你的意思是“获取垃圾回收”的东西。垃圾收集器收集时当然看起来在值类型;那些值类型可能是活和保持到一个引用类型:

struct S { public string str; }
...
S s = default(S); // local variable of value type
s.str = M(); 

当垃圾收集器运行时,它当然看起来在s,因为它需要确定s.str仍然活着。

我的建议:澄清的恰恰的你的意思是由动词是什么 “变垃圾收集”

  

GC拾取只有参考类型存储器解除分配。

再次,这不是事实。假设你有一个实例

class C { int x; }

对于整数的存储器将在垃圾收集堆,并且因此被垃圾收集器回收时C的实例变为无根。

为什么你认为只有引用类型的内存由垃圾收集器释放的谎言?正确的说法是,内存是的分配的由垃圾收集器的取消分配的由垃圾收集,我觉得非常有意义。所述GC分配它,所以它是负责清理它。

  

那么与值类型发生,因为他们也对堆栈占用内存?

什么都没有发生在他们。没有什么需要发生在自己身上。堆栈是一百万字节。当线程启动判定堆栈的大小;它开始于一百万字节,它在整个线程的整个执行停留在百万字节。在堆栈上存储既不产生也不破坏;只有它的内容被改变。

有在这个问题中使用,像破坏,再生,释放,除去过多的动词。这不符合实际发生的情况很好地对应。局部变量简单地不再是,挪威鹦鹉风格

一个方法具有一个入口点,即首先发生的事情是,CPU堆栈指针调整。创建本地变量“堆栈帧”,存储空间。在CLR保证这个空间被初始化为0,而不是否则你在C#中使用强烈,因为明确的分配规则的一个特点。

一个方法具有出口的单个点,即使你方法代码穿插着多个return语句。在这一点上,堆栈指针简单地恢复到原来的值。实际上,这“忘记”的局部变量那里曾经有。它们的值是不以任何方式“挑选”,字节仍然存在。但他们不会持续太久,在程序下一次调用将要再次覆盖它们。在CLR零初始化规则确保你永远无法看到那些旧值,这将是不安全的。

非常,非常快,时间不超过在单处理机周期。这种行为在C#语言中的可见的副作用是值类型不能有一个终结。确保没有额外的工作有许多工作要做。

在栈上的值类型是从堆当它的范围之除去。

值类型被破坏,只要他们去的范围进行。

值的类型,将当在它已经执行我假设被移除堆栈帧得到释放

也想添加堆栈是在线程级别,并且堆在应用领域的水平。

因此,当一个线程端部,将通过RECLAM该特定线程使用的堆栈存储器。

在.NET每个值类型实例将是别的部分,其可以是一个更大的封闭值类型实例,一个堆对象,或一个堆栈帧。只要其中的任何一样应运而生,其中的任何结构也将应运而生;那么这些结构将继续只要存在含有它们做的东西。当包含结构的东西不再存在,结构也可以。没有方法来破坏的结构,而不破坏该容器,也没有办法来破坏一些含有一个或多个结构不破坏结构包含在其中。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top