【问题标题】:Is there a way to speed up Javadoc (takes 7 minutes)有没有办法加快 Javadoc(需要 7 分钟)
【发布时间】:2017-05-02 12:55:56
【问题描述】:

我正在为一个包含 2,509 个类的模块构建 Javadoc。目前这需要 7 分钟或每秒 6 个文件。

我试过了

mvn -T 1C install

但是javadoc 只使用 1 个 CPU。有没有办法使用更多和/或加快速度?

我正在使用 Oracle JDK 8 更新 112。我的开发机器有 16 个内核和 128 GB 内存。

运行飞行记录器我可以看到只有一个线程main

对于那些感兴趣的人,我使用了以下选项:

<plugin>
    <artifactId>maven-javadoc-plugin</artifactId>
    <configuration>
        <additionalJOptions>
            <additionalJOption>-J-XX:+UnlockCommercialFeatures</additionalJOption>
            <additionalJOption>-J-XX:+FlightRecorder</additionalJOption>
            <additionalJOption>-J-XX:StartFlightRecording=name=test,filename=/tmp/myrecording-50.jfr,dumponexit=true</additionalJOption>
            <additionalJOption>-J-XX:FlightRecorderOptions=loglevel=debug</additionalJOption>
        </additionalJOptions>
    </configuration>
</plugin>

注意:一种解决方法是:

-Dmaven.javadoc.skip=true

【问题讨论】:

  • Oracle javac 编译器不是多线程的,但 Eclipse 编译器是。 Eclipse 编译器也能生成 javadoc 吗?
  • 我在想 -T 控制 maven 如何启动 javac 编译器进程,javadoc 是一个独立的工具。记录在案的options 很少,例如-verbose 会告诉您它在每个文件上花费了多长时间。
  • 您可能会触发 JavaDoc 错误。大部分时间都花在 HashMap.put() 和 ClassMember.isEqual() 上,这可能表明哈希码算法不佳,导致冲突过多。
  • 它不一定相关,但你通过mvn调用javadoc,所以maven加速可能值得一试,即export MAVEN_OPTS="-client -XX:+TieredCompilation -XX:TieredStopAtLevel=1 -Xverify:none"(参见this blog)。我对此没有太大希望,但谁知道呢?
  • 如果有帮助请查看此链接:issues.apache.org/jira/browse/LUCENE-5282

标签: java javadoc maven-javadoc-plugin


【解决方案1】:

使用 -T1C 运行 maven 将导致 maven 尝试并行构建模块,因此如果您有一个多模块项目,它最多会并行构建每个模块的 javadoc(如果您的模块之间的依赖关系图允许)。

javadoc 进程本身是单线程的,因此您将无法使用多个内核来生成单个模块的 javadoc。

但是,由于您有许多类(可能还有许多 @link doclet 或类似的?),也许 javadoc 进程可以从扩展堆中受益。您是否查看过 GC 活动? 尝试在您的配置中添加它,看看是否有帮助:

<additionalJOption>-J-Xms2g</additionalJOption>
<additionalJOption>-J-Xmx2g</additionalJOption>

【讨论】:

  • 我可以检查内存大小没有限制。这台机器上的默认值应该是 32 GB。
  • @PeterLawrey 问题可能不是限制,而是起始大小。 JVM 只会在每次完全 GC 后扩展一点内存,因此合理数量的 Xms 可以让 JVM 在扩展内存足以满足您的工作负载之前避免过多的 GC
【解决方案2】:

@lbndev 是正确的,至少对于 Javadoc 提供的默认 Doclet (com.sun.tools.doclets.formats.html.HtmlDoclet)。查看源代码可以确认单线程实现:

(这些链接指向 JDK 8 源代码。使用 JDK 11,类已移动,但 HtmlDocletAbstractDoclet 中的基本 for 循环仍然存在。)

一些基于样本的分析证实这些方法是瓶颈:

这不是您希望听到的,但在当前的多线程标准 Javadoc 中似乎没有选项,至少在单个 Maven 模块中是这样。

generateClassFiles() 等很适合多线程,尽管这可能需要在 JDK 中进行更改。正如下面提到的AbstractDoclet.isValidDoclet() 甚至主动阻止HtmlDoclet 的子类化。尝试以第三方的身份重新实现其中一些循环需要引入许多其他代码。

对其他 Doclet 实现(例如javadown)的扫描只发现了围绕包和类向下钻取的类似实现风格。此线程上的其他人可能会知道更多。

考虑得更广泛一点,DocFileFactory 可能还有调整空间。它被清楚地标记为内部类(甚至在包中都不是公共的),但它确实抽象了(HTML)文件的编写。它的替代版本似乎可以在内存中缓冲 HTML,或直接流式传输到 zip 文件,以提高 IO 性能。但显然这也需要了解 JDK 工具变更的风险。

【讨论】:

  • 嗯,HtmlDoclet 的一个狡猾的子类可以覆盖 generateClassFiles() 并引入一个执行器。不过,它需要特定于 JDK。我现在可以检查哪个 JDK 是目标吗?
  • 祝你好运,所有的单例、有状态的类 javac。这是徒劳的。
  • 嗯......这个想法是稍后加入一个新的 doclet 实现 - 作为 -doclet 参数。看起来HtmlDoclet 的实现者看到了这种可能性并将其锁定。 AbstractDoclet.isValidDoclet() 检查子类的完全限定类名是com.sun.tools.doclets.formats.html.HtmlDoclet。它是私有的,并从内部方法调用,因此需要重新实现很多。 JDK 11 中类似。
【解决方案3】:

javadoc 和标准 doclet 目前基本上是单线程的。

主要通过并行生成页面来改进这一点是“在雷达上”,但这意味着将 MT 安全性改进为各种共享数据结构。

【讨论】:

    【解决方案4】:

    您可以让 Maven 在所有内核中为每个内核使用多个线程。

    例如。

    mvn -T 4C install # will use 4 threads per available CPU core
    

    您可以将上面的4 更改为您想要的任何数字。你有一台拥有大量资源的机器。试试816

    您也尝试过使用 javadoc-no-fork 吗?这将确保不会第二次触发 javadoc - https://maven.apache.org/plugins/maven-javadoc-plugin/examples/javadoc-nofork.html

    【讨论】:

    • 这不会改变 javadoc 插件的工作方式。
    • 已在javadoc-no-fork添加信息
    • 听起来值得一试。
    • @PeterLawrey 你试过了吗?
    【解决方案5】:

    Maven 定制是一种加速 javadoc 生成的方法。

    另一种方法是更改​​用于生成 javadoc 的 doclet。 maven javadoc 插件允许您更改用于生成 javadoc 的 doclet

    https://maven.apache.org/plugins/maven-javadoc-plugin/examples/alternate-doclet.html

    我确实发现了以下商业 doclet(我与他们没有任何关系),它声称比传统的 javadoc 更快。它提供免费/试用/商业许可证。如果您真的渴望加快您的 javadoc 构建速度,也许值得看看它是否物有所值

    http://www.filigris.com/docflex-javadoc

    互联网上可能存在开源替代品...

    【讨论】:

      【解决方案6】:

      使用 doxygen 代替您现在使用的常规 mvn。

      【讨论】:

      • 这会加速 javadoc 吗?
      猜你喜欢
      • 2018-11-21
      • 2017-06-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-03
      • 1970-01-01
      • 2017-12-03
      • 1970-01-01
      相关资源
      最近更新 更多