java代码优化 字节码_JVM字节码与代码优化

一.字节码查看

将.java源文件编译成.class二进制字节码文件,运行该字节码文件

1.将class字节码文件内容输出到文本文件当中

javap -v xxx.class > xxx.txt

第一个部分:

显示生成class的java源文件的基本信息

Classfile /C:/Users/FLC/Desktop/授课内容/授课案例/Y2170/day22/jvm_project/jvm_day01/target/classes/com/wdksoft/ClassTest.class

Last modified 2020-3-11; size 585 bytes

MD5 checksum 39fa2636495e5b4bf08da6decc537381

Compiled from "ClassTest.java"

public class com.wdksoft.ClassTest

minor version: 0

major version: 51

flags: ACC_PUBLIC, ACC_SUPER

第二个部分:显示该类所涉及到的常量池,共有35个常量

Constant pool:

#1 = Methodref          #5.#23         // java/lang/Object."":()V

#2 = Fieldref           #24.#25        // java/lang/System.out:Ljava/io/PrintStream;

#3 = Methodref          #26.#27        // java/io/PrintStream.println:(I)V

#4 = Class              #28            // com/wdksoft/ClassTest

#5 = Class              #29            // java/lang/Object

#6 = Utf8              

#7 = Utf8               ()V

#8 = Utf8               Code

#9 = Utf8               LineNumberTable

#10 = Utf8               LocalVariableTable

#11 = Utf8               this

#12 = Utf8               Lcom/wdksoft/ClassTest;

#13 = Utf8               main

#14 = Utf8               ([Ljava/lang/String;)V

#15 = Utf8               args

#16 = Utf8               [Ljava/lang/String;

#17 = Utf8               a

#18 = Utf8               I

#19 = Utf8               b

#20 = Utf8               c

#21 = Utf8               SourceFile

#22 = Utf8               ClassTest.java

#23 = NameAndType        #6:#7          // "":()V

#24 = Class              #30            // java/lang/System

#25 = NameAndType        #31:#32        // out:Ljava/io/PrintStream;

#26 = Class              #33            // java/io/PrintStream

#27 = NameAndType        #34:#35        // println:(I)V

#28 = Utf8               com/wdksoft/ClassTest

#29 = Utf8               java/lang/Object

#30 = Utf8               java/lang/System

#31 = Utf8               out

#32 = Utf8               Ljava/io/PrintStream;

#33 = Utf8               java/io/PrintStream

#34 = Utf8               println

#35 = Utf8               (I)V

第三个部分:显示该类的构造器,编译器自动生成一个无参构造

public com.wdksoft.ClassTest();

descriptor: ()V

flags: ACC_PUBLIC

Code:

stack=1, locals=1, args_size=1

0: aload_0

1: invokespecial #1                  // Method java/lang/Object."":()V

4: return

LineNumberTable:

line 3: 0

LocalVariableTable:

Start  Length  Slot  Name   Signature

0       5     0  this   Lcom/wdksoft/ClassTest;

第四部分:显示main方法的信息

public static void main(java.lang.String[]);

descriptor: ([Ljava/lang/String;)V    方法的描述,V代表返回值为void

flags: ACC_PUBLIC, ACC_STATIC     方法修饰符 public  static

Code:

stack=2, locals=4, args_size=1    stack代表操作栈的大小   locals本地变量表大小    args_size代表参数个数

0: iconst_2        将数据2压入到操作栈当中,位于栈顶

1: istore_1        从操作栈当中弹出一个数据,放到本地变量表当中,下标为1,0是this,操作栈当中数据清空

2: iconst_5        将数据5压入到操作栈当中,位于栈顶

3: istore_2        从操作栈当中弹出一个数据,放到本地变量表当中,下标为2,0是this,操作栈当中数据清空

4: iload_2         将本地变量表中的下标为2的数据压入到操作站

5: iload_1         将本地变量表中的下标为1的数据压入到操作站

6: isub         将操作栈中的两个数据相减

7: istore_3        将相减的结果压入到本地本地变量表当中,下标为3

8: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;

11: iload_3         将本地变量表中下标为3的数据压入到操作站

12: invokevirtual #3                  // Method java/io/PrintStream.println:(I)V

15: return         返回

LineNumberTable:        行号列表

line 5: 0

line 6: 2

line 7: 4

line 8: 8

line 9: 15

LocalVariableTable:

Start  Length  Slot  Name   Signature

0      16     0  args   [Ljava/lang/String;

2      14     1     a   I

4      12     2     b   I

8       8     3     c   I

二.动态字节技术

在程序运行或者编译时期,通过动态字节码技术对类新增,删除,修改类的内部结构,包括字段和方法

动态字节码技术应用场景:AOP,Lombok,动态修改class文件等等

字节码操作类库:

1.BCEL

2.ASM:轻量级的Java字节码操作框架,SpringAOP底层基于ASM字节码技术

3.CGLIB 基于ASM

4.javassist

通过javap命令查看class文件的字节码内容

1.1创建一个简单的测试类:

public class Test {

public static void main(String[] args) {

int a=2;

int b=5;

int c=b-a;

System.out.println(c);

}

}

1.2 cmd打开窗口,使用如下命令:

javap ‐v Test.class > Test.txt

1.3查看Test01.txt文件,内容如下:

Classfile /G:/学习/Y2/Test/Test01.class

Last modified 2020-3-9; size 576 bytes

MD5 checksum e263d731887a9c6376ddab948c1efa19

Compiled from "Test01.java"

public class com.my.Test.Test01

minor version: 0

major version: 51

flags: ACC_PUBLIC, ACC_SUPER

Constant pool:

#1 = Methodref #5.#23 // java/lang/Object."":()V

#2 = Fieldref #24.#25 // java/lang/System.out:Ljava/io/PrintStream;

#3 = Methodref #26.#27 // java/io/PrintStream.println:(I)V

#4 = Class #28 // com/wn/Test/Test01

#5 = Class #29 // java/lang/Object

#6 = Utf8

#7 = Utf8 ()V

#8 = Utf8 Code

#9 = Utf8 LineNumberTable

#10 = Utf8 LocalVariableTable

#11 = Utf8 this

#12 = Utf8 Lcom/wn/Test/Test01;

#13 = Utf8 main

#14 = Utf8 ([Ljava/lang/String;)V

#15 = Utf8 args

#16 = Utf8 [Ljava/lang/String;

#17 = Utf8 a

#18 = Utf8 I

#19 = Utf8 b

#20 = Utf8 c

#21 = Utf8 SourceFile

#22 = Utf8 Test01.java

#23 = NameAndType #6:#7 // "":()V

#24 = Class #30 // java/lang/System

#25 = NameAndType #31:#32 // out:Ljava/io/PrintStream;

#26 = Class #33 // java/io/PrintStream

#27 = NameAndType #34:#35 // println:(I)V

#28 = Utf8 com/wn/Test/Test01

#29 = Utf8 java/lang/Object

#30 = Utf8 java/lang/System

#31 = Utf8 out

#32 = Utf8 Ljava/io/PrintStream;

#33 = Utf8 java/io/PrintStream

#34 = Utf8 println

#35 = Utf8 (I)V

{

public com.my.Test.Test01();

descriptor: ()V

flags: ACC_PUBLIC

Code:

stack=1, locals=1, args_size=1

0: aload_0

1: invokespecial #1 // Method java/lang/Object."":()V

4: return

LineNumberTable:

line 3: 0

LocalVariableTable:

Start Length Slot Name Signature

0 5 0 this Lcom/wn/Test/Test01;

public static void main(java.lang.String[]);

descriptor: ([Ljava/lang/String;)V

flags: ACC_PUBLIC, ACC_STATIC

Code:

stack=2, locals=4, args_size=1

0: iconst_2

1: istore_1

2: iconst_5

3: istore_2

4: iload_2

5: iload_1

6: isub

7: istore_3

8: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;

11: iload_3

12: invokevirtual #3 // Method java/io/PrintStream.println:(I)V

15: return

LineNumberTable:

line 5: 0

line 6: 2

line 7: 4

line 8: 8

line 9: 15

LocalVariableTable:

Start Length Slot Name Signature

0 16 0 args [Ljava/lang/String;

2 14 1 a I

4 12 2 b I

8 8 3 c I

}

SourceFile: "Test01.java"

二.代码优化

所谓代码优化是指对程序代码进行等价(指不改变程序的运行结果)变换。程序代码可以是中间代码(如四元式代码),也可以是目标代码。等价的含义是使得变换后的代码运行结果与变换前代码运行结果相同。优化的含义是最终生成的目标代码短(运行时间更短、占用空间更小),时空效率优化。原则上,优化可以在编译的各个阶段进行,但最主要的一类是对中间代码进行优化,这类优化不依赖于具体的计算机。

在不改变程序运行效果的前提下,对被编译的程序进行等价变换,使之能生成更加高效的目标代码。

明确一个概念,对方法的调用,即使方法中只有一句 语句,也是有消耗的。

for (int i = 0; i < list.size(); i++)

{...}

建议替换为:

int length = list.size();

for (int i = 0, i < length; i++)

{...}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值