如何避免GC暂停?

时间:2016-12-18 12:07:21

标签: java garbage-collection jvm

我们的应用程序对延迟至关重要。为了减少GC暂停,我们重用了对象。在这个过程的开始,我们分配了许多小对象,然后(几乎)没有分配内存。但是,我仍然看到以下gc:

的日志
namespace X
{
    using System;

    /// <see cref="I1"/>  (or <see cref="X.I1"/> from outside X)
    /// <see cref="T:X.I1"/>
    interface I1
    {
        /// <see cref="I1.M1(int)"/>  (or <see cref="M1(int)"/> from inside I1)
        /// <see cref="M:X.I1.M1(System.Int32)"/>
        void M1(int p);

        /// <see cref="I1.M2{U}(U)"/>
        /// <see cref="M:X.I1.M2``1(``0)"/>
        void M2<U>(U p);

        /// <see cref="I1.M3(Action{string})"/>
        /// <see cref="M:X.I1.M3(System.Action{System.String})"/>
        void M3(Action<string> p);
    }

    /// <see cref="I2{T}"/>
    /// <see cref="T:X.I2`1"/>
    interface I2<T>
    {
        /// <see cref="I2{T}.M1(int)"/>
        /// <see cref="M:X.I2`1.M1(System.Int32)"/>
        void M1(int p);

        /// <see cref="I2{T}.M2(T)"/>
        /// <see cref="M:X.I2`1.M2(`0)"/>
        void M2(T p);

        /// <see cref="I2{T}.M3{U}(U)"/>
        /// <see cref="M:X.I2`1.M3``1(``0)"/>
        void M3<U>(U p);
    }
}

据我所知,JVM会停止进程以遍历所有引用并标记对象。这是对的吗?

此外,我发现此类日志的频率会随着时间而减少。所以我认为GC会调整一些内部参数,我希望在一开始就提供它们。现在我使用以下参数运行进程:

2016-12-18T13:51:48.650+0200: 1.085: Total time for which application threads were stopped: 0.0001411 seconds, Stopping threads took: 0.0000203 seconds
2016-12-18T13:51:48.776+0200: 1.210: Total time for which application threads were stopped: 0.0002027 seconds, Stopping threads took: 0.0000183 seconds
2016-12-18T13:51:48.894+0200: 1.328: Total time for which application threads were stopped: 0.0002559 seconds, Stopping threads took: 0.0000194 seconds
2016-12-18T13:51:48.906+0200: 1.341: Total time for which application threads were stopped: 0.0002159 seconds, Stopping threads took: 0.0000199 seconds
2016-12-18T13:51:49.047+0200: 1.482: Total time for which application threads were stopped: 0.0002842 seconds, Stopping threads took: 0.0000208 seconds

所有其他参数都与详细说明GC有关。我们的机器有足够的内存来完全避免gc。我怎么解释它到java?

OS:Linux,JVM oracle或openJDK。

谢谢。

1 个答案:

答案 0 :(得分:2)

这些不一定是垃圾收集。

当JVM打印Total time for which application threads were stopped时,还有许多其他情况(与GC无关)。有关详细信息,请参阅the related answer

由于类加载和重新编译,非GC安全点在应用程序启动时尤其频繁。

如果要跟踪GC暂停,请使用-XX:+PrintGCDetails

<强>更新

减少非GC安全点数量的一些技巧:

  • -XX:-UseBiasedLocking完全禁用偏差撤销暂停;
  • -XX:+UnlockDiagnosticVMOptions -XX:GuaranteedSafepointInterval=0每秒禁用强制性安全点;
  • -XX:-TieredCompilation禁用多层编译,从而减少了与重新编译相关的安全点的数量。

注意:这只是一个提示,而不是生产用途的建议。以上选项可能会产生性能副作用。