查找方法的字节码大小

我试图找出一个方法的字节码大小,因为我想确保它足够小,可以通过编译器优化来内联。

我看到内联方法的默认最大大小是35,所以如果方法大于那个,我将修改代码或将其分解为多个方法。

我有一个方法生成下面的字节码(通过IntelliJ IDEA的ASM字节码大纲插件反汇编)。

如何判断该方法的字节码大小? LINENUMBER似乎引用了原始源代码的行号。

TIA

public static mergeNativeArrays([Ljava/lang/Object;[Ljava/lang/Object;IZ)[Ljava/lang/Object; L0 LINENUMBER 865 L0 ALOAD 0 ASTORE 4 L1 LINENUMBER 867 L1 ILOAD 2 IFGE L2 L3 LINENUMBER 868 L3 ALOAD 0 ARRAYLENGTH ISTORE 2 L2 LINENUMBER 870 L2 FRAME APPEND [[Ljava/lang/Object;] ILOAD 2 ALOAD 1 ARRAYLENGTH IADD ISTORE 5 L4 LINENUMBER 872 L4 ALOAD 4 ARRAYLENGTH ILOAD 5 IF_ICMPGE L5 L6 LINENUMBER 874 L6 ILOAD 3 IFEQ L7 L8 LINENUMBER 875 L8 ILOAD 5 INVOKESTATIC railo/commons/math/MathUtil.nextPowerOf2 (I)I ISTORE 5 L7 LINENUMBER 877 L7 FRAME APPEND [I] ILOAD 5 ANEWARRAY java/lang/Object ASTORE 4 L9 LINENUMBER 878 L9 ALOAD 0 ICONST_0 ALOAD 4 ICONST_0 ALOAD 0 ARRAYLENGTH INVOKESTATIC java/lang/System.arraycopy (Ljava/lang/Object;ILjava/lang/Object;II)V L5 LINENUMBER 881 L5 FRAME SAME ALOAD 1 ICONST_0 ALOAD 4 ILOAD 2 ALOAD 1 ARRAYLENGTH INVOKESTATIC java/lang/System.arraycopy (Ljava/lang/Object;ILjava/lang/Object;II)V L10 LINENUMBER 883 L10 ALOAD 4 ARETURN L11 LOCALVARIABLE dst [Ljava/lang/Object; L0 L11 0 LOCALVARIABLE src [Ljava/lang/Object; L0 L11 1 LOCALVARIABLE dstPosition I L0 L11 2 LOCALVARIABLE doPowerOf2 Z L0 L11 3 LOCALVARIABLE result [Ljava/lang/Object; L1 L11 4 LOCALVARIABLE newSize I L4 L11 5 MAXSTACK = 5 MAXLOCALS = 6 

如何判断该方法的字节码大小?

一种方法是将它们添加起来:-)

每个字节码指令由主指令的1个字节加上固定数量的操作数字节组成。


更实用的方法是使用javap -c转储包含字节码的类文件。 输出包括每条指令的字节偏移量。

参考: http : //docs.oracle.com/javase/7/docs/technotes/tools/windows/javap.html


1)我可以将ALOAD 0 ASTORE 4添加为4个字节,但是如何使用ARRAYLENGTH或INVOKESTATIC方法名称?

JVM规范的第6.5节中列出了这些说明 – http://docs.oracle.com/javase/specs/jvms/se7/html/index.html

  1. 向下滚动到索引的相关部分。
  2. 单击指令的链接。
  3. 阅读“格式”和“描述”以确定使用了多少字节。

按照这个过程,我推断出ARRAYLENGTH是1个字节,INVOKESTATIC是3个字节。

2)我试图使用javap,但由于某种原因我得到了类(它在jar中,我将-classpath filename.jar传递给javap,但它不起作用)。

再次阅读javap手册条目。 如果你正确使用它确实有效。 (也许您没有以正确的格式提供完全限定的类名。)