繁体   English   中英

JDK8 编译慢

[英]slow JDK8 compilation

尝试在一个大项目上升级到 JDK8,与 JDK7 相比,JDK8 上的编译速度非常慢。

以详细模式运行编译器,JDK8 编译器在从服务器到客户端的实体生成的大型转换器类(映射)处停止。 在某些情况下,转换器方法会调用来自同一 Mapping 类的其他转换器方法。

作为一种解决方法,尝试将映射文件拆分为多个文件。 这在仅编译 Mapping 类或其包含项目(projectA)时明显提高了性能。 但是对于从 projectA 调用转换器方法的其他项目,编译时间非常慢。

另一种解决方法是让所有 convert 方法返回 null,而不调用任何其他方法。 同样,项目 A 的性能良好,但不适合依赖项目。

ProjectA 使用泛型,但由于它与 JDK6 兼容,JDK6 没有引入广义类型推断,因此可能是另一个 JDK8 错误导致了这种速度变慢。

因此可能脱离上下文但对于广义类型推断,如下所示的一些线程建议升级到 JDK9。 但由于它还没有发布,所以它不是一个可行的升级选项。 如果将修复程序向后移植到 JDK8,那将是理想的。 这是在以下 StackOverflow 线程中请求的,但 Oracle 团队尚未回复。

使用 jOOQ 3.6+、普通 SQL 和 javac 编译器进行慢速编译

我附上了 2 张关于堆在 JDK7 和 JDK8 中的外观的屏幕截图。 这可能是 JDK8 减速的原因吗?

谢谢!

更新 20160314

来自 Mapping 类的转换器方法如下所示:

public static ResponseItemVO convert (ResponseItem pArg0){
         if(pArg0==null){
             return null;
         }
        ResponseItemVO ret = new ResponseItemVO();
        ret.setErrorDetails(pArg0.getErrorDetails());
        ret.setResult(Mapping.convert(pArg0.getResult()));
        ret.setIdentifier(Mapping.convert(pArg0.getIdentifier()));
        return ret;
    }

VO 看起来像:

public class ResponseItemVO extends ResultVO<IdentifierVO, DetailsVO >  {
    public ResponseItemVO() {}
}

JDK7 堆: JDK7-堆 JDK8 堆: JDK8-heap

您已经注意到,当涉及到基于通用目标类型的重载解析时,Java 8 中存在严重的性能退化 您的情况的原因之一可能是编译器需要从赋值类型中找到适当的方法

ResultVO<Something, Something> result = Mapping.convert(...);
// heavy lookup here ---------------------------^^^^^^^

如果您可以控制代码生成器,并且不受向后兼容性的限制,那么可能值得考虑避免convert()方法的重载。 如果没有重载,编译器不必在映射代码内部或调用站点执行重载解析工作。 这肯定会快得多。

尝试 1:通过在方法名称中使用参数类型:

class Mapping {
    public static ResponseItemVO convertResponseItem(ResponseItem pArg0){
        if (pArg0==null){
            return null;
        }
        ResponseItemVO ret = new ResponseItemVO();
        ret.setErrorDetails(pArg0.getErrorDetails());
        ret.setResult(Mapping.convertResult(pArg0.getResult()));
        ret.setIdentifier(Mapping.convertIdentifier(pArg0.getIdentifier()));
        return ret;
    }
}

尝试 2:通过将 convert 方法移到别处,例如移入VO类型

class ResponseItemVO {
    public static ResponseItemVO from(ResponseItem pArg0){
        if (pArg0==null){
            return null;
        }
        ResponseItemVO ret = new ResponseItemVO();
        ret.setErrorDetails(pArg0.getErrorDetails());
        ret.setResult(ResultVO.from(pArg0.getResult()));
        ret.setIdentifier(IdentifierVO.from(pArg0.getIdentifier()));
        return ret;
    }
}

或更好...

class ResponseItem {
    public ResponseItemVO toVO(){
        ResponseItemVO ret = new ResponseItemVO();
        ret.setErrorDetails(getErrorDetails());
        ret.setResult(getResult().toVO());
        ret.setIdentifier(getIdentifier().toVO());
        return ret;
    }
}

暂无
暂无

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

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