当垃圾收集(When to Garbage Collect)

2019-06-26 06:34发布

我有一段代码在内存中加载一个非常大的图像。 因此,它似乎是一个合理的事情打电话

System.gc();

之前加载图像。 从我可以告诉它没有问题的作品。

昨天,我决定使用的软件叫的非常有用的一块FindBugs的 ,它可以扫描你的代码并报告可能导致错误或一般不建议战略问题。 问题是,这段代码我提到被报道。 该描述是这样的:

...强制垃圾收集; 除了在基准测试代码非常可疑

它接着阐述:

守则明确调用垃圾收集。 除了在基准测试的具体使用,这是非常可疑的。

在过去,人们有明确的情况下,在调用例程,如关闭或完成方法,导致巨大的性能黑洞的垃圾收集器。 垃圾收集器可以是昂贵的。 强制垃圾收集的数百或数千任何情况下会带来机器抓取。

所以我的问题是: 这难道不是确定以编程方式调用垃圾收集器在这种情况下? 我的代码仅调用一次,它是在方法被很少使用。 如果这也不行叫它那么你应该在的情况下做的,你做得非常内存密集型操作之前需要尽可能多的内存可能,你需要释放尽可能多的内存更多钞票之前呢?

Answer 1:

你有没有得到任何的性能改进与System.gc()的? 我不这么认为,因为你可能没有很多的对象是需要收集您加载图像之前。

通常现代化的垃圾收集器最好知道什么时候才能运行,所以你不应该强制征收的,除非你有一个非常很好的理由。 (例如,如通过该插件提出了基准申请)

BTW:调用System.gc()建议将VM执行“完全”或“大”的集合,这意味着所有线程都停止不久。 否则,将很可能只会使“小”的垃圾收集,不停止所有的线程。

与-verbose运行程序:GC,看看有多少字节被收集。

还有大量的技术资料,对垃圾收集在这里: http://java.sun.com/developer/technicalArticles/Programming/GCPortal/



Answer 2:

通常情况下,GC是比你聪明,所以最好还是让它运行每当运行时决定。 如果运行时需要的内存,它会运行GC本身



Answer 3:

它的优良调用垃圾收集器,你没有得到任何“问题”。 不过,我怀疑这将significently提高性能,除非该呼叫也与整理磁盘碎片分配的数据交易。 我不知道。

你应该在这种情况下,做的是分析代码。 运行了好几次,看看你会得到什么样的结果。



Answer 4:

通常情况下,你不应该与垃圾收集器干扰。 如果有必要加载图像之前释放一些内存,那么垃圾回收器会为你做它。

无论如何,如果你只是做一次,它可能不会严重影响你的表现。 循环中完成的事重要得多。



Answer 5:

你已经得到了很多很好的建议,我会尽量不重申。

如果你真正得到与GC问题,比如你的应用程序的句号了一秒钟,请执行以下操作:1.检查,有没有对System.gc任何电话(); 2.检查出的各种选项来配置GC。 有吨的周围,并且他们更乐于助人,然后强迫GC。



Answer 6:

确保大对象可以尽早gc'ed。 即设置变量为空和/或让他们掉出的范围。 这有助于!



Answer 7:

如果内存分配失败,GC周期开始和分配再次尝试。



Answer 8:

一般来说,没有。 这是不恰当的调用System.gc()。 但是,我有地方是有道理的少数病例。

在我写的软件,有一个内置的性能跟踪层。 它在自动测试大多使用,但可以在现场被用于诊断目的。 测试之间的或特定的运行后,我们将调用System.gc几次,然后记录在记忆仍然存在。 它为我们提供了一段时间看内存消耗趋势线基本内存占用基准。 虽然这可能与一些外部JVM接口来完成,这是比较容易做的很到位,因此无需确切的数字。

在一个更老的系统,我们可以有72级独立的JVM(是的,72,有在施工时它一个很好的理由)向上。 在该系统中,离开堆到自由浮动在所有72级的JVM可能会产生一些过度(远远超出物理存储器)总的内存消耗。 的System.gc()被调用大量数据练习之间,试图保持JVM接近平均保持增长,从堆(加盖堆可能是另一个方向,但随后将需要实施者到每个站点配置越来越更明白什么是引擎盖下发生得到它的权利,并没有系统负载下失效)的。



文章来源: When to Garbage Collect