我读了很多关于垃圾收集的文章,几乎所有的文章都提到了堆内存,所以我的问题是 "垃圾收集是收集堆内存还是堆内存,还是两者都收集"。
它收集的是堆内存。通常情况下,堆内存被收集 自动 当执行路径到达作用域的终点时,例如。
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
变量。
堆内存。
垃圾回收是一种对不再使用的内存进行重新分配的方法。有时,"不再使用 "这部分是很棘手的。有了堆,只要一个函数返回,我们就可以确信(除了程序员错误)局部变量没有被使用了,所以几乎在每个languageruntime中,它们都会在那个时候被自动deallocated。
栈之所以被称为 "栈",正是因为它是内存的一个区域,用 "栈策略 "来管理,也就是LIFO(Last In, First Out)。如果在栈上的分配不是以 "栈的方式 "进行的,那就不叫栈,而是叫堆。
垃圾收集是为了应对在堆上分配东西的问题而发明的,即这样你无法预测哪些部分会先被释放。GC是为了解决堆管理不够用的内存分配问题。
栈是最后一个在先 出 所以没有必要去收集垃圾。
--栈是你的方法参数和局部变量所在的地方,如果你离开方法,栈指针会自动递减(或递增,取决于具体的方法)。
栈是你的方法参数和局部变量所在的地方。如果你离开方法,栈指针会自动递减(或递增,这取决于具体的实现)。这对大多数编程语言都是如此。
相反,垃圾回收只在堆上工作。
除非你使用的是我们都不知道的剖析器,否则堆是主要的关注点。这是因为大多数人只是对一个备受赞誉的工具告诉他们的任何事情做出反应。请到这篇文章的末尾看看,大多数指出静态分配内存错误的剖析工具都是 平时 正确。剖析应该超越简单的泄漏和垃圾收集。
我举个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个线程同时进入这个函数,结果肯定是垃圾,除非我的编译器奇迹般地发现了我的 意思 并引入互斥或动态分配,而不用我操心,这时我们又回到了剖析堆的问题上。
简而言之,在我们这辈子,垃圾收集与堆有关。指望将来有些人在堆上动刀子,试图 "优化 "一些东西,然后指望这种努力成为一帮CEO会要求的解释语言。
这并不意味着忽视内存 错误 是一件好事,不管存储的情况如何。
至少在java中,当你离开那个堆栈框架时,堆栈会自动去分配,所以没有必要进行垃圾回收。
我是java程序员,所以没有这个问题,但其实在C++中,(听说)你要小心这个问题,因为你可以在栈上分配对象,你可以离开那个栈帧,对象就会被去分配,你不能再使用它,等等。
你没有引用任何特定的技术,但这种用法在各语言中相当典型。
垃圾收集器只在托管堆上工作。在一个进程中可能有多个堆,其中一些堆没有被垃圾收集。
当一个方法返回时,堆上分配的变量会被deallocated。垃圾收集器将使用这些变量来寻找实时引用,但它不会收集内存。
Garbage Collector In Java只在Heap内存上工作,而不在堆栈内存上工作,因为堆栈工作的主要原则是(Last In First Out).这本身就说明了这一切.l即当函数的作用域结束时,堆栈会自动清空。