java中的垃圾收集器方法有什么用?

时间:2018-05-24 08:07:11

标签: java garbage-collection

System.gc()或Runtime.gc()如果你打电话,不能保证会有垃圾收集。它由JVM来执行GC。那么有这样的方法有什么意义呢?

5 个答案:

答案 0 :(得分:4)

System.gc()Runtime.gc()的javadoc暗示可以配置JVM来忽略对这些方法的调用;例如使用-XX:+DisableExplicitGC JVM选项。

但是,默认情况下它们没有这样配置(至少在当前版本的Oracle和OpenJDK Java中)。因此,默认情况下,调用会执行某些操作。

话虽如此,在大多数情况下直接调用垃圾收集器是个坏主意。它们很少合理的情况大部分都包括在内:

  • 如果您正在尝试调查或测试GC敏感代码的行为;例如终结

  • 如果您试图在不方便的地方避免GC暂停,请在用户不会注意到的位置运行GC。

  

在我请求System.gc()时,我不明白提供有保证的GC会出现什么问题?

当您能够通过gc()调用调用垃圾收集器时,通常会执行完整收集。这是昂贵的,特别是当非垃圾数据量大 1 时。不幸的是,很多Java程序员都没有意识到这一点。因此,(据我所知)JVM选项忽略显式gc()调用的主要原因是为了减轻程序员滥用方法的潜在灾难性性能影响。

如果您 希望您的System.gc()来电启动GC,那么最好的建议是确保您不要在JVM选项中包含-XX:+DisableExplicitGC

阅读java命令的Oracle手册条目以获取更多信息。

1 - 垃圾收集的大部分运行时成本是跟踪和复制仍可访问的对象的图形。如果您告诉收集器在需要之前运行,则会降低其效率。相比之下,JVM本身知道堆何时已满,或者足够接近以确保集合是有保证的。实际上,它可以优化两种不同的要求;最大化吞吐量或最小化GC暂停时间。

答案 1 :(得分:2)

来自Java 7 docs

  

public static void gc()

     

运行垃圾收集器。

     

拨打gc   方法建议Java虚拟机花费精力   回收未使用的对象,以便创建它们当前的内存   占用可快速重复使用。当控制从方法返回时   呼叫,Java虚拟机已尽最大努力回收空间   来自所有丢弃的物品。

     

调用System.gc()实际上等同于调用:

     

调用Runtime.getRuntime()。GC()

所以,基本上,这是GC启发式的一个建议,现在是释放一些记忆的好时机。例如,假设您正在编写一个帧速率锁定为60FPS的游戏。每帧的预算为16.6(当然重复;)毫秒。假设你的帧只需要5ms就可以运行。通常,您会使用Thread.sleep等待剩余时间。但是,您可以选择先拨打System.gc(),告诉虚拟机“嘿,我有一些额外的时间 - 在我等待时随时清理”。当然,您无法保证垃圾收集的剩余时间少于11.6MS!但是如果仔细地完成它可以帮助你的内存使用并防止垃圾收集在一个糟糕的时间发生。类似的原则适用于其他类型的应用程序 - 基本上,如果您知道您的应用程序将有一些停机时间,您可以让VM知道System.gc()并希望阻止GC改为决定在某些事情中运行重要的。

答案 2 :(得分:0)

基本上你是对的,不能保证jvm会在System.gc()电话后立即启动gc。然而,gc可以记录你现在愿意收集并实际运行它。

这取决于jvm,但据我所知,热点jvm实际上在System.gc()Runtime.gc()之后运行gc,至少大部分时间都是如此。

所以我会说没有至少一种方法来建议运行gc运行gc会是一个错误。可以有不同的vm实现,如果有一个vm想要提供调用gc的可能性并保证它会在这样的调用之后实际运行,它不会破坏规范并且它可能对某些情况有用,如果正如我已经提到的那样,hotspot vm很可能不会忽略这个电话。

答案 3 :(得分:0)

如果有人想要抓住垃圾收集(这对旧JVM有效),则会提供这些方法,但是将垃圾部分留在JVM上总是明智的。现代JVM实现具有高度优化的垃圾收集器。 modren JVM实现使我们的工作变得简单,所以我们只关注java代码。

答案 4 :(得分:0)

你是对的,在没有用例的情况下,首先不应该提供gc()个电话。我可以想到使用显式GC调用至少有一个正面和两个负面点:

  1. 如果您正在构建一个您无法控制JVM选项并希望在代码中实现某些神级调整的应用程序,则可以使用显式调用。但请放心,在您突然期望几分钟的低负载的情况下,这不是一个神奇的调用来完成GC。您可能需要投入大量精力来实现这一目标,例如估算GC的响应能力,要收集的内存量等等。

  2. System.gc()Runtime.getRuntime().gc()可以作为提醒或建议,但这完全是JVM的特权。相反,在看到这样的要求时,它可能根本不会做任何事情。参考:Oracle Java

  3. 话虽如此,它通常被避免,因为GC可以通过外部JVM选项而不是代码本身来控制和处理。例如:-XX:-DisableExplicitGC