简体   繁体   English

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

[英]How to check bytecode length of java method

At this moment I participate in big legacy project with many huge classes and generated code. 目前,我参加了一个大型遗留项目,其中包含许多巨大的类和生成的代码。 I wish to find all methods that have bytecode length bigger than 8000 bytes (because OOTB java will not optimize it). 我希望找到所有字节码长度大于8000个字节的方法(因为OOTB Java不会对其进行优化)。

I found manual way like this: How many bytes of bytecode has a particular method in Java? 我发现这样的手动方式: Java中有多少字节的字节码具有特定的方法? , however my goal is to scan many files automatically. ,但是我的目标是自动扫描许多文件。

I tried to use jboss-javassist, but AFAIK getting bytecode length is available only on class level. 我尝试使用jboss-javassist,但是AFAIK获取字节码长度仅在类级别可用。

Huge methods might indeed never get inlined, however, but I have my doubts regarding the threshold of 8000. This comment suggests a much smaller limit, though it is platform and configuration dependent anyway. 当然,可能永远也不会内联庞大的方法,但是我对8000的阈值感到怀疑。 此注释建议的限制要小得多,尽管无论如何它还是取决于平台和配置。

You are right that getting bytecode length needs to process classes on that low level, however, you didn't specify what actual obstacle you encountered when trying to do that with Javassist. 没错,获取字节码长度需要在较低的级别上处理类,但是,您没有指定使用Javassist进行处理时遇到的实际障碍。 A simple program doing that with Javassist, would be 用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");
    }
}

This has been written and tested with a recent version of Javassist that uses Generics in the API. 已使用在API中使用泛型的Javassist的最新版本进行了编写和测试。 If you have a different/older version, you have to use 如果您使用其他版本/旧版本,则必须使用

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");
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM