如何检查java方法的字节码长度

时间:2018-01-19 09:55:37

标签: java bytecode bytecode-manipulation jvm-bytecode

此刻,我参与了许多大型课程和生成代码的大型遗留项目。 我希望找到所有字节码长度大于8000字节的方法(因为OOTB java不会优化它)。

我发现这样的手动方式:How many bytes of bytecode has a particular method in Java? ,但我的目标是自动扫描多个文件。

我尝试使用jboss-javassist,但AFAIK获取字节码长度仅在类级别上可用。

1 个答案:

答案 0 :(得分:4)

然而,巨大的方法可能永远不会被内联,但我怀疑8000的阈值。This comment建议一个小得多的限制,尽管它依赖于平台和配置。

你是对的,获取字节码长度需要处理低级别的类,但是,你没有指定在尝试使用Javassist时遇到的实际障碍。使用Javassist执行该操作的简单程序将是

try(InputStream is=javax.swing.JComponent.class.getResourceAsStream("JComponent.class")) {
    ClassFile​ cf = new ClassFile(new DataInputStream(is));
    for(MethodInfo mi: cf.getMethods()) {
        CodeAttribute ca = mi.getCodeAttribute();
        if(ca == null) continue; // abstract or native
        int bLen = ca.getCode().length;
        if(bLen > 300)
            System.out.println(mi.getName()+" "+mi.getDescriptor()+", "+bLen+" bytes");
    }
}

这是使用最新版本的Javassist编写和测试的,该版本在API中使用了Generics。如果您有不同的/旧版本,则必须使用

try(InputStream is=javax.swing.JComponent.class.getResourceAsStream("JComponent.class")) {
    ClassFile​ cf = new ClassFile(new DataInputStream(is));
    for(Object miO: cf.getMethods()) {
        MethodInfo mi = (MethodInfo)miO;
        CodeAttribute ca = mi.getCodeAttribute();
        if(ca == null) continue; // abstract or native
        int bLen = ca.getCode().length;
        if(bLen > 300)
            System.out.println(mi.getName()+" "+mi.getDescriptor()+", "+bLen+" bytes");
    }
}