2012-07-26 123 views
5

我刚刚开始使用C#作为我的语言。我有点理解Java中GC的概念,并且今天在.NET中重新讨论了相同的概念。垃圾收集是否影响堆栈?

在C#中,值类型被放到堆栈上(与Java的情况相同,其中局部变量放入堆栈)。但在C#中,即使struct也包含在值类型中。所以,即使struct被放置在堆栈上。在最糟糕的情况下,如果有很多方法调用,并且堆栈使用很多方法大量填充,并且每种方法都有许多本地值类型,并且许多本身有许多本地值类型的垃圾收集器会影响堆栈?从我研究的内容(部分是我被教的内容),我明白它不会这样做。主要是因为操作堆栈内容会涉及很多开销,而且GC只会参考堆栈来查找引用 - 除此之外无非就是如此。

只是要添加另一个相关主题相关的问题:强制调用GC(如Java中的System.gc(),不确定C#等价物),并不能确保GC例程在那里被调用。那么我应该在哪里发出这样的电话 - 我希望我需要GC运行,或任何随机的地方,因为不能保证我的电话会立即触发GC?或者我应该把这些东西放到运行环境中而不用担心呢?

注:我添加了Java标记,因为我试图从那里链接概念。我知道GC在两个独立的运行时环境中的内部功能肯定会有所不同,但我想基本概念是一样的。

回答

2

垃圾收集不会影响java堆栈上的对象。

GC只影响jvm堆中的对象。 Java GC进程是多层次的,可能非常复杂,值得一读。查看一个网站,如:http://javarevisited.blogspot.com/2011/04/garbage-collection-in-java.html,以便更好地掌握它的运作方式。

至于强制系统的GC 这是一个坏主意。当GC需要运行时,jvm会有更好的想法。如果你正在尝试分配一个大对象,那么jvm将确保这个空间在那里,而你不需要告诉它运行GC。

编辑 我不好,你比C#更关心java。应用相同的内存管理原则,堆栈不受影响,不明确运行GC等.C#旨在以与java相似的方式运行。 http://msdn.microsoft.com/en-us/library/ms973837.aspx

+0

感谢您的回答。阅读更多内容后我会回来。 – 2012-07-26 14:58:34

1

编号AFAIK GC不影响堆栈。它只影响HEAP内存。堆栈框架将在方法调用时创建,并将在方法退出时删除。

编辑

MSDN article解释了.NET框架是如何GC的作品。

+0

这对于Java,C#或两者都适用? – 2012-07-26 14:32:23

+0

这仅适用于JAVA。我对c#不太了解,但我的猜测是C#遵循类似的原则。 – kosa 2012-07-26 14:32:53

+0

我的问题是在C#的情况下,但感谢您的回应。 – 2012-07-26 14:33:59

2

堆栈不需要垃圾收集器的帮助;因为当你移出堆栈帧(堆栈中当前执行的范围)时,当你创建一个新的堆栈帧时,整个帧(包括内容)被释放(并被覆盖)。

function foo(int a, int b) { 
    int i; 
    doStuff(); 
} 

创建一个堆栈帧(粗略可视化)

---- Frame Start ---- 
(value for parameter a) 
(value for parameter b) 
(other items needed for tracking execution) 
(extra stack frame space 
    (value for stack allocated i) 
) 
---- End of Frame ---- 

当进入一个函数,堆栈分配的变量被分配为帧被分配,在离开帧时,整个帧被丢弃,重新分配帧分配变量的内存。

请记住,Java通常在堆栈上分配对象引用和堆栈本地基元,而不是整个对象。最近的几次优化只允许栈内分配的对象在帧外不可访问;它有这样的条件,它不被认为是你可以指望的东西。

也就是说,栈帧中的引用通常指向堆,这是垃圾正常收集。

+0

我明白堆栈的概念。但是在最坏的情况下,我曾经问过堆栈中有很多函数调用(一个函数调用另一个函数等等,其他框架没有弹出堆栈)。但我现在有点理解,无论如何,堆栈不会受到影响。 – 2012-07-26 15:00:39

+1

如果需要足够的堆栈以超过为堆栈空间分配的内存,则帧不会移动到堆中。而是发生stackoverflow错误,并停止处理。 – 2012-07-26 15:13:35

+0

我希望我能更好地回答你的答案,甚至接受它,我非常喜欢它,因为你让我很好地理解了堆栈场景,并且还提醒我存在一个名为stackoverflowerror的东西。但另一个答案提供了一个整体解决方案。不过谢谢。 – 2012-07-27 15:15:56