尝试在一个大项目上升级到JDK8,与JDK7相比,JDK8上的编译速度非常慢。
以详细模式运行编译器,JDK8编译器停止在从服务器到客户端的实体的大生成转换器类(映射)。 在几种情况下,转换器方法从同一个Mapping类调用其他转换器方法。
作为一种解决方法,尝试将Mapping文件拆分为多个文件。仅在编译Mapping类或包含项目(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放缓的原因吗?
谢谢!
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() {}
}
答案 0 :(得分:2)
在基于通用目标类型的重载解析时,您已经注意到了there's a severe performance regression in Java 8。您的情况中的一个原因可能是编译器需要从赋值类型
中找到适当的方法ResultVO<Something, Something> result = Mapping.convert(...);
// heavy lookup here ---------------------------^^^^^^^
如果您控制代码生成器,并且不受向后兼容性的限制,则可能值得考虑避免convert()
方法的重载。在没有重载的情况下,编译器不必在映射代码内部或调用站点上执行重载解析工作。这肯定会快得多。
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;
}
}
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;
}
}