垃圾收集

nam*_*ked 8 language-agnostic computer-science garbage-collection

我无法理解垃圾收集中的一些事情.

首先,数据如何分配空间?即在堆栈或堆上(据我所知,所有静态或全局变量都在堆栈上分配空间,局部变量在堆上分配空间).

其次,GC运行堆栈或堆上的数据?即像Mark/Sweep这样的GC算法会将堆栈上的数据称为root set right吗?然后通过检查堆上的哪些变量引用根集来映射堆上的所有可到达变量.

如果程序没有全局变量怎么办?算法如何工作呢?

问候,黑暗

Jus*_*ier 11

它可能有助于澄清您询问的平台GC - JVM,CLR,Lisp等.这说:

首先退一步,通常在堆栈上分配某些局部变量.然而,细节可能因语言而异.以C#为例,只有本地值类型和方法参数存储在堆栈中.因此,在C#中,foo将在堆栈上分配:

public function bar() { 
    int foo = 2;
    ...
}
Run Code Online (Sandbox Code Playgroud)

或者,动态分配的变量使用堆中的内存.这应该是直观有意义的,否则堆栈必须在每次new调用时动态增长.此外,这意味着这些变量只能用作分配它们的本地函数中的本地变量,这当然不是真的,因为我们可以拥有(例如)类成员变量.因此,从C#中获取另一个示例,在以下情况下result在堆上分配:

public class MyInt
{         
    public int MyValue;
}

...
MyInt result = new MyInt();
result.MyValue = foo + 40;
...
Run Code Online (Sandbox Code Playgroud)

现在考虑到这一背景,堆上的内存被垃圾收集.堆栈上的内存不需要GC,因为当前函数返回时将回收内存.在较高级别,GC算法通过跟踪在堆上动态分配的所有对象来工作.一旦分配通过new,该对象将由GC跟踪,并在它不再在范围内时收集,并且不再有对它的引用.