Language agnostic 垃圾收集器收集堆栈内存、堆内存还是两者都收集?

Language agnostic 垃圾收集器收集堆栈内存、堆内存还是两者都收集?,language-agnostic,memory-management,garbage-collection,stack,heap,Language Agnostic,Memory Management,Garbage Collection,Stack,Heap,我读了很多关于垃圾收集的文章,几乎所有的文章都是关于堆内存的。所以我的问题是“垃圾收集收集堆栈内存或堆内存或两者兼有”。堆内存 垃圾收集是一种释放不再使用的内存的方法。有时,“不再使用”部分很棘手。有了堆栈,只要函数返回,我们就可以确信(程序员错误除外)局部变量不再被使用,因此几乎在每种语言/运行时都会自动释放它们 堆栈是后进先出的,因此不需要进行垃圾收集 --纠正了——哼 它收集堆内存。通常,当执行路径到达作用域的末尾时,会自动收集堆栈内存。e、 g: void fun() { int n

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

堆内存


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

堆栈是后进先出的,因此不需要进行垃圾收集


--纠正了——哼

它收集堆内存。通常,当执行路径到达作用域的末尾时,会自动收集堆栈内存。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++语言中,堆栈分配的变量称为“代码> Audio/Cuff>变量”。

堆栈是方法参数和局部变量所在的位置。如果离开该方法,堆栈指针将自动递减(或递增,具体取决于具体实现)。大多数编程语言都是这样


相反,垃圾收集只在堆上工作。

至少在java中,当您离开堆栈帧时,堆栈将自动取消分配,因此无需进行垃圾收集


我是java程序员,所以我没有这个问题,但实际上C++中,(我听说)你必须要小心,因为你可以在堆栈上分配对象,你可以离开这个栈框架,对象将被分配,你不能再使用它了。等等< /P> < P>你不引用任何特定的技术,但是这种用法在不同的语言中是相当典型的

垃圾收集器仅在托管堆上工作。一个进程中可能有多个堆,其中一些堆不是垃圾收集的


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

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

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

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

int main(void)
{
   char *am_i_leaking;

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

   return 0;
}
编译器如何分配,这取决于编译器。如果您使用它并且可以处理结果,那么您可能有一个坏掉的编译器。然而,如果我有100个线程同时进入该函数,那么结果肯定是垃圾,除非我的编译器神奇地理解了我的意思,并引入互斥或动态分配,而我不必担心它,此时我们回到了分析堆

简而言之,在我们的一生中,垃圾收集属于堆。指望将来会有一些尝试,并试图“优化”事情,然后指望这些努力成为一批首席执行官需要的解释性语言

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

堆栈之所以称为“堆栈”,正是因为它是一个内存区域,由“堆栈策略”(又名后进先出)管理。如果堆栈上的分配不是以“堆栈方式”完成的,它将不是堆栈而是堆


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

Java中的垃圾收集器只在堆内存上工作,而不在堆栈内存上工作,因为堆栈工作的主要主体是(后进先出)。这就解释了这一切。也就是说,当到达函数作用域的末尾时,堆栈自动为空。

复制。你当然是说后进先出。是的,但别叫我雪莉。不。在C++中,函数返回时自动存储在堆栈上的对象。但是您可以在堆上分配一个对象,并将指向该对象的指针存储在堆栈上;然后,当函数返回并离开堆栈帧时,将丢失指针的唯一副本,从而泄漏对象。如果C++内置了垃圾收集(它是可选的),这就不是问题。@ Dave Hinton:你可以把指针分配给当前堆栈框架上分配的对象,到另一个堆栈框架,然后感到惊讶,对吧?否?在Java中,堆栈上不存储任何对象;它只保存对那里的对象的引用。所有实际对象都在堆中。Java方法结束后,引用丢失,但堆中的对象仍然存在。在C++中,对象可以直接放置在堆栈上,并且在函数结束后内存区域无效。
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;
}