C2编译器在启动时使CPU饱和

时间:2014-10-07 21:38:08

标签: java performance jvm

我在Java 7上有一个java servlet应用程序,在系统资源消耗方面通常非常健康。通常,服务器上的CPU使用率低于50%。然而,在启动后的几分钟内,它的行为有很大不同,以至于如果CPU在此期间尝试提供大量流量,则可以在几分钟内将其固定为100%。结果是响应时间慢,网络超时,甚至有时甚至是长时间的垃圾收集暂停。

为了诊断问题,我在服务器启动时进行了一系列的线程转储,同时运行了顶级-H。通过将每个java线程与pid匹配,我可以始终看到C2 CompilerThread使用到目前为止最多的CPU。我已经研究了这个线程的作用,我理解它是一个基于运行时统计信息优化代码的Java编译器。但是从我所做的所有阅读中,我无法说明改善情况的最佳方法。我能收集的唯一选择是:

  1. 从C2切换到TieredCompiler(但这会在启动后的前几分钟内获得更好的性能吗?)
  2. 启用-XX:+ PrintCompilation以查看正在优化的内容(但我如何处理此信息?在服务器以某种方式接受流量之前,我可以强制优化它吗?)
  3. 最佳方法是什么?是否有其他选项可以在启动后尝试缓解CPU使用情况?

2 个答案:

答案 0 :(得分:0)

有几种付费的JVM技术可以使用提前编译来缓解您的问题。

但是,如果你想坚持使用标准JVM,人们使用的一个技巧是在启动后发送一些虚拟请求,以便在实际操作开始之前预热JVM。这样,您可以在为客户提供服务之前决定何时支付JVM预热成本。

您也可以 强制JVM按热点的-Xcomp命令行选项编译所有代码 ,但我们不推荐因为它会通过编译很少使用的代码来减慢应用程序的启动速度。

答案 1 :(得分:0)

第一次调用instrumentation.retransformClasses(clazz);后,我遇到了同样的问题。 instrumentation是关于Java代理的java.lang.instrument。

这是retransformClasses从JDK源代码执行的操作。

    /**
     * Retransform the supplied set of classes.
     *
     * <P>
     * This function facilitates the instrumentation
     * of already loaded classes.
     * When classes are initially loaded or when they are
     * {@linkplain #redefineClasses redefined},
     * the initial class file bytes can be transformed with the
     * {@link java.lang.instrument.ClassFileTransformer ClassFileTransformer}.
     * This function reruns the transformation process
     * (whether or not a transformation has previously occurred).
     * This retransformation follows these steps:
     *  <ul>
     *    <li>starting from the initial class file bytes
     *    </li>
     *    <li>for each transformer that was added with <code>canRetransform</code>
     *      false, the bytes returned by
     *      {@link java.lang.instrument.ClassFileTransformer#transform transform}
     *      during the last class load or redefine are
     *      reused as the output of the transformation; note that this is
     *      equivalent to reapplying the previous transformation, unaltered;
     *      except that
     *      {@link java.lang.instrument.ClassFileTransformer#transform transform}
     *      is not called
     *    </li>
     *    <li>for each transformer that was added with <code>canRetransform</code>
     *      true, the
     *      {@link java.lang.instrument.ClassFileTransformer#transform transform}
     *      method is called in these transformers
     *    </li>
     *    <li>the transformed class file bytes are installed as the new
     *      definition of the class
     *    </li>
     *  </ul>
     * <P>
     *
     * The order of transformation is described in the
     * {@link java.lang.instrument.ClassFileTransformer#transform transform} method.
     * This same order is used in the automatic reapplication of retransformation
     * incapable transforms.
     * <P>
     *
     * The initial class file bytes represent the bytes passed to
     * {@link java.lang.ClassLoader#defineClass ClassLoader.defineClass} or
     * {@link #redefineClasses redefineClasses}
     * (before any transformations
     *  were applied), however they might not exactly match them.
     *  The constant pool might not have the same layout or contents.
     *  The constant pool may have more or fewer entries.
     *  Constant pool entries may be in a different order; however,
     *  constant pool indices in the bytecodes of methods will correspond.
     *  Some attributes may not be present.
     *  Where order is not meaningful, for example the order of methods,
     *  order might not be preserved.
     *
     * <P>
     * This method operates on
     * a set in order to allow interdependent changes to more than one class at the same time
     * (a retransformation of class A can require a retransformation of class B).
     *
     * <P>
     * If a retransformed method has active stack frames, those active frames continue to
     * run the bytecodes of the original method.
     * The retransformed method will be used on new invokes.
     *
     * <P>
     * This method does not cause any initialization except that which would occur
     * under the customary JVM semantics. In other words, redefining a class
     * does not cause its initializers to be run. The values of static variables
     * will remain as they were prior to the call.
     *
     * <P>
     * Instances of the retransformed class are not affected.
     *
     * <P>
     * The retransformation may change method bodies, the constant pool and attributes.
     * The retransformation must not add, remove or rename fields or methods, change the
     * signatures of methods, or change inheritance.  These restrictions maybe be
     * lifted in future versions.  The class file bytes are not checked, verified and installed
     * until after the transformations have been applied, if the resultant bytes are in
     * error this method will throw an exception.
     *
     * <P>
     * If this method throws an exception, no classes have been retransformed.
     * <P>
     * This method is intended for use in instrumentation, as described in the
     * {@linkplain Instrumentation class specification}.
     *
     * @param classes array of classes to retransform;
     *                a zero-length array is allowed, in this case, this method does nothing
     * @throws java.lang.instrument.UnmodifiableClassException if a specified class cannot be modified
     * ({@link #isModifiableClass} would return <code>false</code>)
     * @throws java.lang.UnsupportedOperationException if the current configuration of the JVM does not allow
     * retransformation ({@link #isRetransformClassesSupported} is false) or the retransformation attempted
     * to make unsupported changes
     * @throws java.lang.ClassFormatError if the data did not contain a valid class
     * @throws java.lang.NoClassDefFoundError if the name in the class file is not equal to the name of the class
     * @throws java.lang.UnsupportedClassVersionError if the class file version numbers are not supported
     * @throws java.lang.ClassCircularityError if the new classes contain a circularity
     * @throws java.lang.LinkageError if a linkage error occurs
     * @throws java.lang.NullPointerException if the supplied classes  array or any of its components
     *                                        is <code>null</code>.
     *
     * @see #isRetransformClassesSupported
     * @see #addTransformer
     * @see java.lang.instrument.ClassFileTransformer
     * @since 1.6
     */
    void
    retransformClasses(Class<?>... classes) throws UnmodifiableClassException;