首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >慢速JDK8编译

慢速JDK8编译
EN

Stack Overflow用户
提问于 2016-03-14 15:14:22
回答 1查看 2.1K关注 0票数 2

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

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

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

另一种解决方法是使所有转换方法返回null,而不是调用任何其他方法。同样,对于projectA来说,性能是好的,但对于依赖于项目则不是这样。

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

因此,除了泛化的类型推断之外,下面的一些线程建议升级到JDK9。但是,由于它还没有发布,作为升级,它不是一个可行的选择。如果对JDK8执行修复的后端端口,这将是非常理想的。这是在下面的StackOverflow线程中请求的,但Oracle尚未答复。

Slow compilation with jOOQ 3.6+, plain SQL, and the javac compiler

我附上了两个屏幕截图,说明堆在JDK7和JDK8中的样子。这会是JDK8放缓的原因吗?

谢谢!

更新20160314

映射类中的转换器方法如下所示:

代码语言:javascript
复制
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看起来是:

代码语言:javascript
复制
public class ResponseItemVO extends ResultVO<IdentifierVO, DetailsVO >  {
    public ResponseItemVO() {}
}

JDK7堆:

JDK8堆:

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-03-14 17:17:36

您已经注意到,当涉及到基于通用目标类型的重载解析时,there's a severe performance regression in Java 8。在这种情况下,原因之一可能是编译器需要从赋值类型中找到适当的方法。

代码语言:javascript
复制
ResultVO<Something, Something> result = Mapping.convert(...);
// heavy lookup here ---------------------------^^^^^^^

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

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

代码语言:javascript
复制
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:将转换方法移到其他地方,例如进入VO类型

代码语言:javascript
复制
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;
    }
}

或者更好..。

代码语言:javascript
复制
class ResponseItem {
    public ResponseItemVO toVO(){
        ResponseItemVO ret = new ResponseItemVO();
        ret.setErrorDetails(getErrorDetails());
        ret.setResult(getResult().toVO());
        ret.setIdentifier(getIdentifier().toVO());
        return ret;
    }
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35991287

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档