java提供了从语言角度能够强制jvm进行垃圾回收,在我们的程序中可以通过调用System.gc去强制jvm进行垃圾回收,通过源码我们可以看到实际上是调用了Runtime去强制gc
public static void gc() {
Runtime.getRuntime().gc();
}
Runtime的gc方法是native方法也就是Rumtime.c中的
JNIEXPORT void JNICALL
Java_java_lang_Runtime_gc(JNIEnv *env, jobject this)
{
JVM_GC();
}
而JVM_GC方法是在jvm.cpp中实现
JVM_ENTRY_NO_ENV(void, JVM_GC(void))
JVMWrapper("JVM_GC");
if (!DisableExplicitGC) {
Universe::heap()->collect(GCCause::_java_lang_system_gc);
}
JVM_END
我们看到参数DisableExplicitGC,从代码中可以使用-XX:+DisableExplicitGC 可以关闭system,gc
对universe:heap() -> Universe::_collectedHeap 是在初始化的时候决定使用什么类型的heap,也决定了使用什么gc的策略,也就是说java heap的分配方式是在java启动的时候就决定的,无法中间更改,同样对应的gc策略也无法更改
if (UseParallelGC) {
#ifndef SERIALGC
Universe::_collectedHeap = new ParallelScavengeHeap();
#else // SERIALGC
fatal("UseParallelGC not supported in java kernel vm.");
#endif // SERIALGC
} else if (UseG1GC) {
#ifndef SERIALGC
G1CollectorPolicy* g1p = new G1CollectorPolicy_BestRegionsFirst();
G1CollectedHeap* g1h = new G1CollectedHeap(g1p);
Universe::_collectedHeap = g1h;
#else // SERIALGC
fatal("UseG1GC not supported in java kernel vm.");
#endif // SERIALGC
} else {
GenCollectorPolicy *gc_policy;
if (UseSerialGC) {
gc_policy = new MarkSweepPolicy();
} else if (UseConcMarkSweepGC) {
#ifndef SERIALGC
if (UseAdaptiveSizePolicy) {
gc_policy = new ASConcurrentMarkSweepPolicy();
} else {
gc_policy = new ConcurrentMarkSweepPolicy();
}
#else // SERIALGC
fatal("UseConcMarkSweepGC not supported in java kernel vm.");
#endif // SERIALGC
} else { // default old generation
gc_policy = new MarkSweepPolicy();
}
Universe::_collectedHeap = new GenCollectedHeap(gc_policy);
}
从源码中我们可以看到
Parallel GC 是用的是ParallelScavengeHeap,
CMS 使用的是 GenCollectdHeap
G1使用的是G1CollectedHeap