Как проверить длину байт-кода метода Java
В данный момент я участвую в большом унаследованном проекте со множеством огромных классов и сгенерированным кодом. Я хотел бы найти все методы, которые имеют длину байт-кода больше, чем 8000 байт (потому что OOTB Java не будет оптимизировать его).
Я нашел ручной способ, например, такой: сколько байтов байт-кода имеет определенный метод в Java? Однако моя цель - сканировать многие файлы автоматически.
Я пытался использовать jboss-javassist, но AFAIK получение длины байт-кода доступно только на уровне класса.
1 ответ
Огромные методы могут действительно никогда не быть встроенными, но у меня есть сомнения относительно порогового значения 8000. Этот комментарий предлагает гораздо меньший предел, хотя в любом случае он зависит от платформы и конфигурации.
Вы правы, что получение длины байт-кода должно обрабатывать классы на этом низком уровне, однако вы не указали, с каким реальным препятствием вы столкнулись при попытке сделать это с 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, которая использует Generics в API. Если у вас другая / старая версия, вы должны использовать
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");
}
}