JDK8编译缓慢

丹·L。

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

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

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

另一个解决方法是使所有convert方法都返回null,而不调用其他任何方法。同样,该性能对于projectA而言不错,但对于依赖项目则不然。

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堆

卢卡斯·埃德(Lukas Eder)

您已经注意到,基于通用目标类型的重载解析方面,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;
    }
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章