认识JVM
认识JVM规范:重点是理解JVM规范的作用,了解JVM规范的主要内容
认识JVM:是什么、有什么、能干什么
JVM:Java virtual machine,也就是java虚拟机
所谓的虚拟机是指:通过软件模拟的具有完整硬件系统功能、运行在一个完全隔离环境中的计算机系统
JVM是通过软件来模拟Java字节玛的指令集,是Java程序运行的环境
java如何实现平台无关
JVM主要功能
1、通过ClassLoader寻找和装在class文件
2、解释字节码成为指令并执行,提供class文件运行环境
3、运行期间内存非配
4、提供硬件交互的平台
虚拟机是平台无关的保障
JVM规范作用
1.Java虚拟机规范为不同的硬件平台提供了一种编译Java技术代码的规范。
2.该规范使用Java软件独立于平台,因为编译是针对作为虚拟机的“一般机器”而做。
3.这个“一般机器”可用软件模拟并运行于各种现存的计算机系统,也可用硬件来实现。
JVM规范定义的主要内容
字节码指令集(相当于中央处理器CPU),详看JVM虚拟机规范
class文件格式
数据类型和值,详看JVM虚拟机规范
运行时数据区
栈帧
特殊方法
<init>:实例初始化方法,通过invokespecial指令来调用
<clinit>:类或接口的初始化方法,不包含参数,返回void
类库
Java虚拟机必须要对一些Java类库提供支持,否则这些类库根本无法实现,比如(反射、加载和创建类或接口,如ClassLoader、连接或初始化类和接口的类、安全,如security、多线程、弱引用)
异常处理
虚拟机的启动、加载、链接和初始化
Java虚拟机规范下载地址
https://docs.oracle.com/javase/specs/index.html
class文件格式
1
| <index> <opcode> [<operand1> [<operand2> ...]][<comment>]
|
class文件格式说明
constant_pool_count:是从1开始的
不同的常亮类型,用tag来区分的,它后面对应的info结构是不一样的
L表示对象,[表示数组,V表示void
了解预定义attribute的含义
stack:方法执行时,操作栈的深度
Locals:局部变量所需的存储空间,单位是slot
slot:是虚拟机为局部变量分配内存所使用的最小单位
arg_size:参数个数,为1的话,因实例方法会默认传入this,locals也会预留一个slot来存放
TestJVM.java原始文件
1 2 3 4 5 6 7 8 9 10
| package world.ismyfree.demo;
public class TestJvm {
public static final String HELLO_JAVA = "hello java";
public static void main(String[] args) { System.out.println(String.format("get message = %s", HELLO_JAVA)); } }
|
TestJVM.class原始文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| cafe babe 0000 0034 002d 0a00 0400 1909 001a 001b 0800 1c07 001d 0700 1e08 001f 0a00 2000 210a 0022 0023 0100 0a48 454c 4c4f 5f4a 4156 4101 0012 4c6a 6176 612f 6c61 6e67 2f53 7472 696e 673b 0100 0d43 6f6e 7374 616e 7456 616c 7565 0100 063c 696e 6974 3e01 0003 2829 5601 0004 436f 6465 0100 0f4c 696e 654e 756d 6265 7254 6162 6c65 0100 124c 6f63 616c 5661 7269 6162 6c65 5461 626c 6501 0004 7468 6973 0100 1d4c 776f 726c 642f 6973 6d79 6672 6565 2f64 656d 6f2f 5465 7374 4a76 6d3b 0100 046d 6169 6e01 0016 285b 4c6a 6176 612f 6c61 6e67 2f53 7472 696e 673b 2956 0100 0461 7267 7301 0013 5b4c 6a61 7661 2f6c 616e 672f 5374 7269 6e67 3b01 000a 536f 7572 6365 4669 6c65 0100 0c54 6573 744a 766d 2e6a 6176 610c 000c 000d 0700 240c 0025 0026 0100 1067 6574 206d 6573 7361 6765 203d 2025 7301 0010 6a61 7661 2f6c 616e 672f 4f62 6a65 6374 0100 1b77 6f72 6c64 2f69 736d 7966 7265 652f 6465 6d6f 2f54 6573 744a 766d 0100 0a68 656c 6c6f 206a 6176 6107 0027 0c00 2800 2907 002a 0c00 2b00 2c01 0010 6a61 7661 2f6c 616e 672f 5379 7374 656d 0100 036f 7574 0100 154c 6a61 7661 2f69 6f2f 5072 696e 7453 7472 6561 6d3b 0100 106a 6176 612f 6c61 6e67 2f53 7472 696e 6701 0006 666f 726d 6174 0100 3928 4c6a 6176 612f 6c61 6e67 2f53 7472 696e 673b 5b4c 6a61 7661 2f6c 616e 672f 4f62 6a65 6374 3b29 4c6a 6176 612f 6c61 6e67 2f53 7472 696e 673b 0100 136a 6176 612f 696f 2f50 7269 6e74 5374 7265 616d 0100 0770 7269 6e74 6c6e 0100 1528 4c6a 6176 612f 6c61 6e67 2f53 7472 696e 673b 2956 0021 0005 0004 0000 0001 0019 0009 000a 0001 000b 0000 0002 0006 0002 0001 000c 000d 0001 000e 0000 002f 0001 0001 0000 0005 2ab7 0001 b100 0000 0200 0f00 0000 0600 0100 0000 0300 1000 0000 0c00 0100 0000 0500 1100 1200 0000 0900 1300 1400 0100 0e00 0000 4300 0600 0100 0000 15b2 0002 1203 04bd 0004 5903 1206 53b8 0007 b600 08b1 0000 0002 000f 0000 000a 0002 0000 0008 0014 0009 0010 0000 000c 0001 0000 0015 0015 0016 0000 0001 0017 0000 0002 0018
|
javap -verbose TestJVM.class(助记符)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
| Classfile /home/anakin/IdeaProjects/untitled/target/classes/world/ismyfree/demo/TestJvm.class Last modified 2021-8-8; size 764 bytes MD5 checksum b5c5da06a2ed9a50c599a61bf2f71066 Compiled from "TestJvm.java" public class world.ismyfree.demo.TestJvm minor version: 0 major version: 52 flags: ACC_PUBLIC, ACC_SUPER Constant pool: #1 = Methodref #4.#25 // java/lang/Object."<init>":()V #2 = Fieldref #26.#27 // java/lang/System.out:Ljava/io/PrintStream; #3 = String #28 // get message = %s #4 = Class #29 // java/lang/Object #5 = Class #30 // world/ismyfree/demo/TestJvm #6 = String #31 // hello java #7 = Methodref #32.#33 // java/lang/String.format:(Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/String; #8 = Methodref #34.#35 // java/io/PrintStream.println:(Ljava/lang/String;)V #9 = Utf8 HELLO_JAVA #10 = Utf8 Ljava/lang/String; #11 = Utf8 ConstantValue #12 = Utf8 <init> #13 = Utf8 ()V #14 = Utf8 Code #15 = Utf8 LineNumberTable #16 = Utf8 LocalVariableTable #17 = Utf8 this #18 = Utf8 Lworld/ismyfree/demo/TestJvm; #19 = Utf8 main #20 = Utf8 ([Ljava/lang/String;)V #21 = Utf8 args #22 = Utf8 [Ljava/lang/String; #23 = Utf8 SourceFile #24 = Utf8 TestJvm.java #25 = NameAndType #12:#13 // "<init>":()V #26 = Class #36 // java/lang/System #27 = NameAndType #37:#38 // out:Ljava/io/PrintStream; #28 = Utf8 get message = %s #29 = Utf8 java/lang/Object #30 = Utf8 world/ismyfree/demo/TestJvm #31 = Utf8 hello java #32 = Class #39 // java/lang/String #33 = NameAndType #40:#41 // format:(Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/String; #34 = Class #42 // java/io/PrintStream #35 = NameAndType #43:#44 // println:(Ljava/lang/String;)V #36 = Utf8 java/lang/System #37 = Utf8 out #38 = Utf8 Ljava/io/PrintStream; #39 = Utf8 java/lang/String #40 = Utf8 format #41 = Utf8 (Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/String; #42 = Utf8 java/io/PrintStream #43 = Utf8 println #44 = Utf8 (Ljava/lang/String;)V { public static final java.lang.String HELLO_JAVA; descriptor: Ljava/lang/String; flags: ACC_PUBLIC, ACC_STATIC, ACC_FINAL ConstantValue: String hello java
public world.ismyfree.demo.TestJvm(); descriptor: ()V flags: ACC_PUBLIC Code: stack=1, locals=1, args_size=1 0: aload_0 1: invokespecial #1 // Method java/lang/Object."<init>":()V 4: return LineNumberTable: line 3: 0 LocalVariableTable: Start Length Slot Name Signature 0 5 0 this Lworld/ismyfree/demo/TestJvm;
public static void main(java.lang.String[]); descriptor: ([Ljava/lang/String;)V flags: ACC_PUBLIC, ACC_STATIC Code: stack=6, locals=1, args_size=1 0: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream; 3: ldc #3 // String get message = %s 5: iconst_1 6: anewarray #4 // class java/lang/Object 9: dup 10: iconst_0 11: ldc #6 // String hello java 13: aastore 14: invokestatic #7 // Method java/lang/String.format:(Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/String; 17: invokevirtual #8 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 20: return LineNumberTable: line 8: 0 line 9: 20 LocalVariableTable: Start Length Slot Name Signature 0 21 0 args [Ljava/lang/String; } SourceFile: "TestJvm.java"
|
ASM开发
认识ASM
ASM是一个Java字节码操纵框架,它能用来动态生成类或者增强既有类的功能
ASM能直接产生二进制class文件,也可以在类被加入虚拟机之前动态改变类行为,ASM类文件读入信息后,能够改变类行为,分析类信息,甚至能根据要求生成新类。
目前许多框架如cglib、Hibernate、Spring都直接或间接地使用ASM操作字节码
ASM编程模型
ASM核心API
ASM的Core API
ASMifier
1 2 3 4 5 6 7 8 9 10
| <dependency> <groupId>org.ow2.asm</groupId> <artifactId>asm</artifactId> <version>9.2</version> </dependency> <dependency> <groupId>org.ow2.asm</groupId> <artifactId>asm-util</artifactId> <version>9.2</version> </dependency>
|
- 3.idea使用maven命令将jar包copy到当前项目的dependency目录方便调试
1
| mvn dependency:copy-dependencies
|
1
| java -cp .:../dependency/asm-9.2.jar:../dependency/asm-util-9.2.jar org.objectweb.asm.util.ASMifier world.ismyfree.jvm.asm.CC
|
如果本文对你有所帮助,请赏我1个铜板买喵粮自己吃,您的支持是我最大的动力!!!
微信支付
支付宝