问题
我是Java新手,对Java中的垃圾收集器感到困惑。它实际上做了什么以及什么时候开始行动。请描述Java中垃圾收集器的一些属性。
#1 热门回答(104 赞)
Thegarbage collector是一个运行在Java Virtual Machine上的程序,它可以删除Java应用程序不再使用的对象。它是自动内存管理的一种形式。
当典型的Java应用程序正在运行时,它正在创建新对象,例如String和File,但在一定时间之后,这些对象不再使用。例如,看看以下代码:
for (File f : files) {
String s = f.getName();
}
在上面的代码中,217153922是在forloop的每次迭代中创建的。这意味着在每次迭代中,都会分配一小部分内存来生成String对象。
回到代码,我们可以看到,一旦执行了一次迭代,在下一次迭代中,在上一次迭代中创建的String对象不再被使用 - 该对象现在被视为"垃圾"。
最终,我们将开始获得大量垃圾,并且内存将用于不再使用的对象。如果这种情况继续下去,最终Java虚拟机将耗尽空间来创建新对象。
这就是垃圾收集器进入的地方。
垃圾收集器将查找不再使用的对象,并清除它们,释放内存,以便其他新对象可以使用该内存。
在Java中,内存管理由垃圾收集器处理,但在其他语言(如C)中,需要使用诸如malloc和free.Memory management之类的功能自行执行内存管理,这是容易出错的事情之一,可以导致所谓的memory leaks--当不再使用内存时不回收内存的地方。
像垃圾收集这样的自动内存管理方案使程序员不必过多担心内存管理问题,因此他或她可以更专注于开发他们需要开发的应用程序。
#2 热门回答(18 赞)
它释放了分配给程序未被程序使用的对象的内存 - 因此名称为"垃圾"。例如:
public static Object otherMethod(Object obj) {
return new Object();
}
public static void main(String[] args) {
Object myObj = new Object();
myObj = otherMethod(myObj);
// ... more code ...
}
我知道这是非常人为的,但是在你致电otherMethod()之后,原来的Object创建了无法访问 - 这就是垃圾收集的"垃圾"。
在Java中,GC会自动运行,但你也可以使用System.gc()明确地调用它来完成主要的垃圾回收。正如Pascal Thivent指出的那样,你真的不应该这样做,它可能弊大于利(见this question)。
#3 热门回答(9 赞)
如果无法从任何活动线程或任何静态引用访问对象,则该对象可以符合垃圾收集或GC的条件。
换句话说,如果对象的所有引用都为null,则可以说对象符合垃圾回收的条件。循环依赖关系不计入引用,因此如果对象A具有对对象B的引用并且对象B具有对对象A的引用并且它们没有任何其他实时引用,则对象A和B都将有资格进行垃圾收集。
**垃圾收集堆生成 - **
为了在Java中进行垃圾收集,在Heap和4335341215中创建的Java对象分为三个部分或几代,这些被称为asYoung(新)生成,Tenured(旧)生成和堆的Perm Area。
新一代进一步分为三个部分,称为伊甸园空间,幸存者1和幸存者2空间。当一个对象最初在堆中创建时,它会在Eden空间内的新一代中创建,并且在随后的小垃圾收集之后,如果一个对象存活,它将被移动到幸存者1,然后幸存者2在主要垃圾收集之前将该对象移动到旧或终身生成。
Perm spaceof Java Heap是JVM存储有关类和方法,字符串池和类级别详细信息的元数据的位置。
虽然你可以使用System.gc()orRuntime.gc()方法发出请求,但你无法强制JVM运行垃圾收集。
In java.lang.System
public static void gc() {
Runtime.getRuntime().gc();
}
public native void gc(); // note native method
**标记和扫描算法 - **
这是垃圾收集使用的最流行的算法之一。任何垃圾收集算法都必须执行2个基本操作。一,它应该能够检测所有无法访问的对象;其次,它必须回收垃圾对象使用的堆空间,并使空间再次可用于程序。
上述操作由Mark和Sweep算法分两个阶段执行:
标记阶段
扫相