繁体   English   中英

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

[英]What is the use of garbage collector methods in java?

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

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暂停时间。

来自Java 7文档

public static void gc()

运行垃圾收集器。

调用gc方法表明Java虚拟机花费了大量精力来回收未使用的对象,以使其当前占用的内存可用于快速重用。 当控制从方法调用返回时,Java虚拟机已尽最大努力从所有丢弃的对象中回收空间。

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

调用Runtime.getRuntime()。GC()

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

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

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

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

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

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

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM