By default the HotSpot JIT refuses to compile methods bigger than about 8k of bytecode (1). Is there anything that can scan a jar for such methods (2)?
unless you pass
-XX开发者_运维知识库:-DontCompileHugeMethods
Jon Masamitsu describes how interpreted methods can slow down garbage collection and notes that refactoring is generally wiser than
-XX:-DontCompileHugeMethods
Thanks to Peter Lawrey for the pointer to ASM. This program prints out the size of each method in a jar:
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.MethodNode;
public static void main(String[] args) throws IOException {
for (String filename : args) {
System.out.println("Methods in " + filename);
ZipFile zip = new ZipFile(filename);
Enumeration<? extends ZipEntry> it = zip.entries();
while (it.hasMoreElements()) {
InputStream clazz = zip.getInputStream(it.nextElement());
try {
ClassReader cr = new ClassReader(clazz);
ClassNode cn = new ClassNode();
cr.accept(cn, ClassReader.SKIP_DEBUG);
List<MethodNode> methods = cn.methods;
for (MethodNode method : methods) {
int count = method.instructions.size();
System.out.println(count + " " + cn.name + "." + method.name);
}
} catch (IllegalArgumentException ignored) {
}
}
}
}
Checkstyle would probably be good for this - it doesn't work on the 8k limit but the number of executable statements in a method in general. To be honest, this is a limit that you want in practice though.
As you already state, -XX:-DontCompileHugeMethods
is generally a bad idea - it forces the JVM to dig through all that ugly code and try and do something with it, which can have a negative effect on performance rather than a positive one! Refactoring, or better still not writing methods that huge to start with would be the way forward.
Oh, and if the methods that huge ended up there through some human design, and not auto-generated code, then there's probably some people on your team who need talking to...
精彩评论