排查编译缓慢问题

2022-09-02 04:32:35

如何调查和解决编译缓慢的问题

我的项目有大约100个类,编译时间超过45秒,这对我来说似乎很慢。作为参考,我有另一个项目,其中包含50个类,可在3秒内编译。

ps:

  • 我使用maven作为构建工具。编译需要大约50秒(),其中45秒用于运行javac(通过运行该选项进行确认)。mvn clean compile-X
  • 增加内存量没有帮助(-Xms500m)
  • 我可以提供有关我的项目的更多信息,但它相当标准,所以我不确定哪些信息是相关的。

更新

多亏了塔吉尔的想法,我设法找到了罪魁祸首之一。此类将编译时间增加 20 秒:

import org.jooq.DSLContext;
import org.jooq.Field;
import static org.jooq.impl.DSL.field;
import static org.jooq.impl.DSL.round;
import static org.jooq.impl.DSL.sum;


class Test {
  static Object fast(DSLContext sql) {
    Field<Double> a = field("a").cast(Double.class);
    return sql.select()
            .having(round(sum(a).cast(Double.class), 2).ne(0d));
  }
  static Object slow(DSLContext sql) {
    return sql.select()
            .having(round(sum(field("a").cast(Double.class)).cast(Double.class), 2).ne(0d));
  }
}

如果该方法被注释掉,则编译时间将恢复正常。slow


答案 1

故障排除 - 常规方法

您可以从重新创建一个空项目开始,然后逐个添加回包,直到编译时间受到影响 - 这应该可以帮助您识别导致问题的包。

然后,您可以删除包中的所有类并逐个添加回去 - 这应该可以帮助您找到导致问题的类。

然后,您可以从每个类中删除所有方法,并逐个添加回它们,直到看到编译时间增加(您可以通过仅重新编译该类来节省时间)。

具体原因

在这种情况下,似乎根本原因是javac中的一个错误,所以我提交了一个错误报告,该报告已被标记为“JEP 215:javac的分层归因”的副本,目标是在Java 9上修复。

同时,解决方法是在存在使用泛型类型推断的嵌套泛型方法调用时引入局部变量,但不幸的是,这并不总是有效...


答案 2

Java 8的一个不太知名的特性是广义目标类型推理

虽然它允许编写更清晰的代码,但这需要更多的工作。有时,这会导致类型推断问题的指数级复杂性。这是一个已知问题,但遗憾的是仍未解决 - 请参阅 JDK-8055984JDK-8067767Javac

解决方法是在 Java 7 兼容级别编译:,或者只是为了使用更简单的结构。javac -source 7


推荐