在Java中是否可以强制进行垃圾回收?即使有些棘手,我知道System.gc();
和Runtime.gc();
但它们只是建议进行GC。那么如何强制GC呢?
在Java中是否可以强制进行垃圾回收?即使有些棘手,我知道System.gc();
和Runtime.gc();
但它们只是建议进行GC。那么如何强制GC呢?
请注意
方法调用System.runFinalizersOnExit(true)保证在Java关闭之前调用finalizer方法。但是,该方法本质上是不安全的并已被弃用。一种替代方法是使用方法Runtime.addShutdownHook添加“关闭钩子”。
Masarrat Siddiqui
我想在这里补充一些内容。请注意,Java运行在虚拟机上而不是实际的机器上。虚拟机有其自己的与机器通信的方式。它可能因系统而异。现在,当我们调用GC时,我们要求Java的虚拟机调用垃圾回收器。
由于垃圾回收器在虚拟机中,我们无法强制它立即进行清理。相反,我们将我们的请求排队给垃圾回收器。这取决于虚拟机,在特定时间后(这可能因系统而异,通常是当分配给JVM的阈值内存已满时),实际机器将释放空间。 :D
System.gc()
的调用将导致GC清除旧的集合。我不确定GC是否立即运行。然而,即使在循环中多次调用System.gc()
,GC也不会清除Young Collection。要让GC清理Young Collection,必须在循环中分配(例如new byte[1024]
),而不调用System.gc()
。由于某种原因,调用System.gc()
会防止GC清理Young Collection。有一些间接的方法可以强制垃圾回收器。你只需要用临时对象填充堆,直到垃圾回收器执行为止。我已经创建了一个类,以这种方式强制垃圾回收器:
class GarbageCollectorManager {
private static boolean collectionWasForced;
private static int refCounter = 0;
public GarbageCollectorManager() {
refCounter++;
}
@Override
protected void finalize() {
try {
collectionWasForced = true;
refCounter--;
super.finalize();
} catch (Throwable ex) {
Logger.getLogger(GarbageCollectorManager.class.getName()).log(Level.SEVERE, null, ex);
}
}
public int forceGarbageCollection() {
final int TEMPORARY_ARRAY_SIZE_FOR_GC = 200_000;
int iterationsUntilCollected = 0;
collectionWasForced = false;
if (refCounter < 2)
new GarbageCollectorManager();
while (!collectionWasForced) {
iterationsUntilCollected++;
int[] arr = new int[TEMPORARY_ARRAY_SIZE_FOR_GC];
arr = null;
}
return iterationsUntilCollected;
}
}
使用方法:
GarbageCollectorManager manager = new GarbageCollectorManager();
int iterationsUntilGcExecuted = manager.forceGarbageCollection();
我不知道这种方法有多少用处,因为它会不断填充堆,但如果您有关键任务应用程序,必须强制GC - 那么这可能是Java可移植的强制GC方式。
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)