Sim*_*son 8 java eclipse maven-2 javac
我有一个Java Maven项目,包含大约800个源文件(一些由javacc/JTB生成),用javac编译需要25分钟.
当我将pom.xml更改为使用Eclipse编译器时,编译大约需要30秒.
有关为什么javac(1.5)运行如此缓慢的任何建议?(我不想永久切换到Eclipse编译器,因为Maven的插件似乎不仅仅是一个小错误.)
我有一个测试用例,很容易重现问题.以下代码在默认包中生成许多源文件.如果您尝试使用javac编译ImplementingClass.java,它似乎会暂停很长时间.
import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintStream;
public class CodeGenerator
{
private final static String PATH = System.getProperty("java.io.tmpdir");
private final static int NUM_TYPES = 1000;
public static void main(String[] args) throws FileNotFoundException
{
PrintStream interfacePs = new PrintStream(PATH + File.separator + "Interface.java");
PrintStream abstractClassPs = new PrintStream(PATH + File.separator + "AbstractClass.java");
PrintStream implementingClassPs = new PrintStream(PATH + File.separator + "ImplementingClass.java");
interfacePs.println("public interface Interface<T> {");
abstractClassPs.println("public abstract class AbstractClass<T> implements Interface<T> {");
implementingClassPs.println("public class ImplementingClass extends AbstractClass<Object> {");
for (int i=0; i<NUM_TYPES; i++)
{
String nodeName = "Node" + i;
PrintStream nodePs = new PrintStream(PATH + File.separator + nodeName + ".java");
nodePs.printf("public class %s { }\n", nodeName);
nodePs.close();
interfacePs.printf("void visit(%s node, T obj);%n", nodeName);
abstractClassPs.printf("public void visit(%s node, T obj) { System.out.println(obj.toString()); }%n", nodeName);
}
interfacePs.println("}");
abstractClassPs.println("}");
implementingClassPs.println("}");
interfacePs.close();
abstractClassPs.close();
implementingClassPs.close();
}
}
Run Code Online (Sandbox Code Playgroud)
你得到了与JDK 1.6相同的行为,包括更新14,构建04,使用G1不会改变行为,(虽然G1看起来效果很好).
使用jvisualvm监视javac,重复的线程转储显示主线程花费大量时间
at com.sun.tools.javac.code.Types.isSubSignature(Types.java:1846)
at com.sun.tools.javac.code.Symbol$MethodSymbol.overrides(Symbol.java:1108)
at com.sun.tools.javac.code.Symbol$MethodSymbol.implementation(Symbol.java:1159)
at com.sun.tools.javac.comp.Check.checkCompatibleConcretes(Check.java:1239)
at com.sun.tools.javac.comp.Check.checkCompatibleSupertypes(Check.java:1567)
at com.sun.tools.javac.comp.Attr.attribClassBody(Attr.java:2674)
at com.sun.tools.javac.comp.Attr.attribClass(Attr.java:2628)
at com.sun.tools.javac.comp.Attr.attribClass(Attr.java:2564)
at com.sun.tools.javac.main.JavaCompiler.attribute(JavaCompiler.java:1036)
at com.sun.tools.javac.main.JavaCompiler.compile2(JavaCompiler.java:765)
at com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:730)
at com.sun.tools.javac.main.Main.compile(Main.java:353)
at com.sun.tools.javac.main.Main.compile(Main.java:279)
at com.sun.tools.javac.main.Main.compile(Main.java:270)
at com.sun.tools.javac.Main.compile(Main.java:69)
at com.sun.tools.javac.Main.main(Main.java:54)
Run Code Online (Sandbox Code Playgroud)
并通过这些类的大量短期实例进行搅拌:
com.sun.tools.javac.code.Types$Subst
com.sun.tools.javac.util.List
com.sun.tools.javac.code.Types$MethodType
Run Code Online (Sandbox Code Playgroud)
我怀疑代码是通过com.sun.tools.javac.comp.Check.checkCompatibleConcretes
比较每个方法与其他方法 来搅拌
那个方法是javadoc:
/** Check that a class does not inherit two concrete methods
* with the same signature.
*/
Run Code Online (Sandbox Code Playgroud)
可能是eclipse的编译器要么不执行该检查,要么不以相同的方式执行它.