是否有可能在Java中强制垃圾收集,即使这很棘手?我知道System.gc();和Runtime.gc ();但他们只建议做GC。如何强制GC?
当前回答
如果需要强制垃圾收集,也许应该考虑如何管理资源。您正在创建持久化在内存中的大对象吗?您是否正在创建具有Disposable接口的大型对象(例如图形类),并且在使用它时不调用dispose() ?您是否在类级别声明了只需要在单个方法中使用的东西?
其他回答
如果需要强制垃圾收集,也许应该考虑如何管理资源。您正在创建持久化在内存中的大对象吗?您是否正在创建具有Disposable接口的大型对象(例如图形类),并且在使用它时不调用dispose() ?您是否在类级别声明了只需要在单个方法中使用的东西?
使用Java™虚拟机工具接口(JVM TI),实现该功能
jvmtiError ForceGarbageCollection(jvmtiEnv* env)
将“强制虚拟机执行垃圾收集。”JVM TI是JavaTM平台调试器体系结构(JPDA)的一部分。
有一些间接的方法来强制垃圾收集器。您只需要用临时对象填充堆,直到垃圾收集器执行为止。我已经创建了一个类,它以这样的方式强制垃圾收集器:
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的可移植方式。
是的,几乎可以强迫你必须以相同的顺序调用方法,同时这些方法是:
System.gc ();
System.runFinalization ();
即使只是一个对象来清理,同时使用这两个方法强制垃圾收集器使用不可达对象的finalize()方法释放分配的内存并执行finalize()方法的状态。
不过是一个可怕的实践使用垃圾收集器,因为使用它可能会引入一个加载的软件可能甚至比在内存坏,垃圾收集器有自己的线程是不可能控制+根据gc可能需要更多的时间和所使用的算法是考虑非常低效,您应该检查您的软件如果它坏在gc的帮助,因为它绝对是坏,一个好的解决方案不能依赖于gc。
注意:只是要记住,只有在finalize方法中没有对对象进行重赋时,这才会起作用,如果发生这种情况,对象将保持存活,它将有一个复活,这在技术上是可能的。
您可以尝试使用Runtime.getRuntime(). GC()或使用实用方法System.gc()注意:这些方法不能确保GC。它们的作用范围应该限制在JVM中,而不是在应用程序中以编程方式处理它。
推荐文章
- 到底是什么导致了堆栈溢出错误?
- 为什么Android工作室说“等待调试器”如果我不调试?
- Java:路径vs文件
- ExecutorService,如何等待所有任务完成
- Maven依赖Servlet 3.0 API?
- 如何在IntelliJ IDEA中添加目录到应用程序运行概要文件中的类路径?
- getter和setter是糟糕的设计吗?相互矛盾的建议
- Android room persistent: AppDatabase_Impl不存在
- Java的String[]在Kotlin中等价于什么?
- Intellij IDEA上的System.out.println()快捷方式
- 使用Spring RestTemplate获取JSON对象列表
- Spring JPA选择特定的列
- URLEncoder不能翻译空格字符
- Java中的super()
- 如何转换JSON字符串映射<字符串,字符串>与杰克逊JSON