为了在一个大型项目上升级到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
映射类中的转换器方法如下所示:
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堆:

JDK8堆:

发布于 2016-03-14 17:17:36
您已经注意到,当涉及到基于通用目标类型的重载解析时,there's a severe performance regression in 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:将转换方法移到其他地方,例如进入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;
}
}https://stackoverflow.com/questions/35991287
复制相似问题