垃圾收集器是否收集堆栈内存,堆内存或两者?

时间:2010-03-26 16:13:54

标签: language-agnostic memory-management garbage-collection stack heap

我阅读了很多关于垃圾收集的文章,几乎所有文章都讲述了堆内存。所以我的问题是“垃圾收集收集堆栈内存或堆内存或两者都有”。

9 个答案:

答案 0 :(得分:17)

它收集堆内存。通常,当执行路径到达范围的末尾时,会自动收集堆栈内存。 e.g:

void fun()
{
  int n; // reservation on the stack as part of the activation record
  ...
} // returning the stack pointer to where it was before entering the scope

事实上,在像C ++这样的语言中,堆栈分配的变量称为auto变量。

答案 1 :(得分:10)

堆内存。

垃圾收集是一种释放不再使用的内存的方法。有时“不再使用”部分是棘手的。使用堆栈,只要函数返回,我们就可以确信(程序员错误除外)局部变量不再被使用,因此它们几乎在每个语言/运行时都会被自动释放。

答案 2 :(得分:5)

堆栈被称为“堆栈”正是因为它是一个内存区域,它使用“堆栈策略”进行管理,即LIFO(后进先出)。如果堆栈上的分配没有以“堆栈方式”完成,那么它就不会被称为堆栈而是堆。

垃圾收集是为了解决在堆上分配事物的问题而发明的,即无法预测哪些部分将首先被释放。 GC适用于堆栈管理不足的内存分配问题。

答案 3 :(得分:2)

Stack是第一个 out 的最后一个,所以不需要垃圾回收。

- 纠正 - 呃!

答案 4 :(得分:1)

堆栈是您的方法参数和局部变量所在的位置。如果离开方法,堆栈指针会自动递减(或根据具体实现递增)。大多数编程语言都是如此。

相比之下,

垃圾收集仅适用于堆。

答案 5 :(得分:1)

除非您使用我们都不知道的分析器,否则堆是主要问题。这是因为大多数人只是对高度赞誉的工具告诉他们的任何反应。请到这篇文章的末尾,看看指出静态分配内存错误的大多数分析工具通常正确。分析应该超越简单的泄漏和垃圾收集。

让我举一个C语言的例子:

#include <stdlib.h>
#include <string.h>

int main(void)
{
   char *am_i_leaking;

   am_i_leaking = strdup("Now, that's subjective!");

   return 0;
}

如果运行此程序的操作系统没有自动回收堆,我就会出现问题。我想不出现实的操作系统没有做到实际使用的操作系统。

现在让我们来看看:

char *foo(void)
{
    static char bar[1024];
    memset(bar, 0, sizeof(bar));
    snprintf(bar, sizeof(bar -1), "Do wa diddy diddy dum diddy do");

    return bar;
}

您的编译器如何分配,这取决于您的编译器。如果你使用它并且可以调整结果,你可能有一个破坏的编译器。然而,如果我有100个线程同时进入该功能,当然,结果是垃圾,除非我的编译器神奇地弄清楚我意味着什么并引入互斥或动态分配而不必担心它,此时我们又回到了分析堆。

简而言之,在我们的生命周期中,垃圾收集与堆有关。指望将来在堆栈中采取一些措施,并试图“优化”事情,然后依靠这种努力成为一群首席执行官将要求的解释性语言。

这并不意味着忽略内存错误是一件好事,无论存储是什么。

答案 6 :(得分:0)

至少在java中,当你离开那个堆栈帧时,堆栈将被自动解除分配,因此不需要垃圾回收。

我是一个java程序员所以我没有这个问题,但事实上在C ++中,(我听说过)你必须小心这个,因为你可以在堆栈上分配对象,你可以留下堆栈框架,对象将被取消分配,你不能再使用它等等。

答案 7 :(得分:0)

您没有引用任何特定技术,但在各种语言中使用相当典型。

垃圾收集器仅适用于托管堆。单个进程中可能有多个堆,其中一些不是垃圾回收。

当方法返回时,在堆栈上分配的变量将被释放。垃圾收集器将使用这些变量来查找实时引用,但它不会收集内存。

答案 8 :(得分:0)

Java中的垃圾收集器仅在堆内存上工作,而不在堆栈内存上工作,因为堆栈所处理的主要原理是(Last In First Out)。这本身就说明了这一切。功能达到堆栈自动为空。