在回答了关于如何用Java强制释放对象的问题(这个人正在清除一个1.5GB的HashMap)后System.gc(),我被告知System.gc()手动调用是不好的做法,但这些评论并不完全令人信服.此外,似乎没有人敢投票,也没有人回答我的回答.
我被告知这是不好的做法,但后来我也被告知垃圾收集器运行不再系统地停止世界,并且它也可以有效地被JVM用作提示,所以我有点像茫然
我知道JVM在需要回收内存时通常比你知道的要好.我也明白,担心几千字节的数据是愚蠢的.我也明白,甚至数兆字节的数据也不是几年前的数据.但仍然,1.5千兆字节?而且你知道内存中有1.5 GB的数据; 它不像是在黑暗中拍摄.是System.gc()系统性的坏,还是有一点它变得好吗?
所以问题实际上是双重的:
System.gc()?它是否仅仅是某些实现中JVM的提示,还是一个完整的收集周期?真的有垃圾收集器实现可以在不停止世界的情况下完成工作吗?请详细说明人们在评论中对我的回答所做的各种断言.System.gc(),或者有时候可以接受?如果是这样,那些时候是什么时候?Java自动调用垃圾收集器,那么为什么我们需要手动调用垃圾收集?什么时候应该使用System.gc()
我不是在寻找通常的"你只能使用System.gc()来回答Java中的GC ",这个问题根本不是什么.
我的问题不是主观的,而是基于现实:GC 可以用Java来强制实现.我们每天使用的许多程序都是这样做的:IntelliJ IDEA,NetBeans,VisualVM.
它们都可以强制 GC发生.
怎么做?
我认为他们都使用JVMTI,更具体地说是ForceGarbageCollection(注意"Force"),但我怎么能为自己尝试呢?
http://java.sun.com/javase/6/docs/platform/jvmti/jvmti.html#ForceGarbageCollection
还要注意,这个问题不是关于"为什么"我想要这样做:"为什么"可能是"好奇心"或"我们正在编写类似于VisualVM的程序"等.
问题是"你如何使用JVMTI的ForceGarbageCollection强制GC"?
是否需要使用任何特殊参数启动JVM?
是否需要任何JNI?如果是这样,究竟是什么代码?
它只适用于Sun VM吗?
任何完整和可编辑的例子都是最受欢迎的.
我的应用程序有很多迭代.直到现在我还没有遇到任何内存问题.但是从代码级别我可以怀疑很少有地方会导致内存泄漏和内存不足问题.我正在考虑手动调用垃圾收集器.手动调用垃圾收集器是一种好习惯吗?
在call-system-gc中明确指出" 你不能"强制"通用JVM进行垃圾收集,因为JVM规范实际上并不需要垃圾收集器. ".我的问题是,是否有这样的JVM(以及它如何以及在何处使用,如果有的话).
public class Main {
public static void main(String[] args) throws InterruptedException {
ClassA a = new ClassA();
a = null;
//Runtime.getRuntime().gc();
Thread.sleep(4000);
}
}
public class ClassA {
@Override
public void finalize(){
System.out.println("cleaned");
}
}
Run Code Online (Sandbox Code Playgroud)
使用上面的代码,finalize()永远不会执行.控制台上没有任何内容.从gc()中删除注释时,执行finalize(),并将"已清除"打印到控制台.为什么我必须明确地调用垃圾收集器?