jvm的前生 诺基亚塞班系统的jar 游戏是 KVM 编译器 长见识了
?
jvm 介绍
jvm 是什么?jvm 是java程序最终运行的地方,jdk默认虚拟机HotSpot,是java能成为跨平台的依仗!(后续介绍到jvm 整体结构的时候会说到是为什么)
大致简略图
类加载器子系统
加载阶段
类加载器分两种:引导类加载器与自定义类加载器。因为引导类加载器是C与C++编写的,扩展类与系统类的加载器都是间接性的继承ClassLoader类来实现的类加载器。扩展类加载器包含系统类加载器,虽然是包含但是实际通过代码 查看他们两个是 同级的。
引导类加载器:负责加载 本地库,包名java开头的jar 或者类
扩展类加载器:负责加载jdk\lib\ext 下面的包
系统类加载器:负责加载开发人员编辑创建的类
双亲委托机制
加载类的时候,首先会逐步向上找到最顶端的加载器
然后加载器根据自身负责加载条件是否满足,满足条件加载,不满足向下传递,让下一个类加载去加载
链接阶段
初始化阶段
赋值操作 举例子如下:
static int c = 1; //链接阶段 c = 0 ,初始化阶段 c = 1
1
双亲委托机制是为了防止:重复加载 和 对核心库的保护。举例子创建一个相同的java.lang.String 如果没有双清委托那么,就会错误的加载类 导致 原本正常的代码中String 的使用出现错误进而导致程序崩溃。
运行时数据区
程序计数器
所谓的程序计数器,可以理解为是一个记录下一个字节码指令的记录地址。执行器通过 程序计数器上找到的地址然后去java 栈中执行。
java 栈(简称 栈)
先看下详情的结构图(一个方法对应一个栈帧)
局部变量表(主要): 记录 非静态类的方法中,隐式关键字this ,形参,局部创建的变量。
操作数栈(主要):每次进行计算机指计算,都会先对值做一次入栈出栈的动作。
方法返回地址:记录每次正常结束或者异常结束之后下一个栈的地址。
动态链接:每次class 文件加载完成之后会有一个常量池,不同的常量对应不同的符号引用,动态链接就是这这些符号引用
一些附加信息:一般是针对内容的附加提示信息,供给给开发人员一定的帮助或者提示。
本地方法栈
负责管理本地方法的库与接口,这些本地方法库是c/c++实现编写的。
堆
结构图:
堆内存大致分为两部分:第一部分 新生代+ 老年代 称谓 堆、第二部分原空间。
堆空间负责存储示例对象以及数组(从jdk7包括7开始新增了字符串常量与静态变量)
元空间 方法区的具体实现 具体下面 方法中介绍。
新生代分为 :Eden 与 s0(Survivor)和s1(Survivor), s0与s1之间有个规则昵称 ‘from’与’to’ 谁空谁就是to ,反之为from 。
Eden 区内部还有一种叫做TLAB 的区域,只有Eden的1%大小,作为线程私有,堆作为共享内存那么就会涉及到线程安全进而涉及到高并发性能 ,TLAB作用就是在一定程度上解决高并发性能的问题。后面会说到怎么解决
默认新生代:老生代 空间大小是 1:2
默认Eden:s0:s1 空间大小是:8:1:1
配置
?-Xms ?? ??? ??? ?堆初始大小
?-Xmx?? ??? ??? ?堆最大
?-XX:NewRatio=1 新生代老年代内存空间比例 默认1:2
?-XX:SurvivorRatio=4 Eden与s0、s1的比例 ?默认8:1:1(提示需要显示配置才生效.)
方法区
本地方法区存储的是(最恰当的一种):类型信息、运行时常量池、静态变量、JIT 代码缓存、域(属性)信息、方法信息。简单理解字节码文件的内容存储到了方法区。元空间 则是方法区的具体实现。
首先要明白方法区就要看懂 字节码文件如下:
/**下面是源码*/?
public class CctvTest {
? ? public static void main(String[] args) {
? ? ? ? CctvTest cctvTest = new CctvTest();
? ? ? ? int z = 19;
? ? ? ? cctvTest.heoll("hl");
? ? }?
? ??
? ? public void heoll(String str) {
? ? ? ? System.out.println("欢迎光临" + str);
? ? ? ? int i = heoll2(10);
? ? }?
? ??
? ? public int heoll2(int i) {
? ? ? ? int c = 1;
? ? ? ? int b = 3;
? ? ? ? String str = heoll3("hl");
? ? ? ? return c + b + i;
? ? }
? ? public String heoll3(String hl) {
? ? ? ? int c = 1;
? ? ? ? int b = 3;
? ? ? ? return hl + "";
? ? }
}
/**下面是反编译class文件拿到的字节码文件*/
//文件信息
Classfile /F:/MyProject/学习开始/houliang/爬虫/NDA/cloud-alibaba-nda/alibaba-data-acquisition/target/test-classes/CctvTest.class
? Last modified 2021-2-22; size 1252 bytes
? MD5 checksum 3fdf47090d6d5e62d4c3ed083dc76af8
? Compiled from "CctvTest.java"
? //类信息
public class CctvTest
? minor version: 0
? major version: 52
? flags: ACC_PUBLIC, ACC_SUPER //修饰关键字
Constant pool: ?//运行时常量池 是数组结构 #1、#2可以理解为下标一样的东西,
//其实可以简单理解,今天要做晚饭 n个菜,我们就需要采购 例如盐味精 白菜 香葱、
//我们不是说 盐都会用到所以按每个菜去买一份盐,而是一份盐 每个菜都用。
//因为方法区只是存储这些信息,具体的实现是元空间所以,想说的是,这里只需要把
//盐、白菜、红酒...等等写好就好了 元空间去实现
? ?#1 = Methodref ? ? ? ? ?#16.#45 ? ? ? ?// java/lang/Object."<init>":()V
? ?#2 = Class ? ? ? ? ? ? ?#46 ? ? ? ? ? ?// CctvTest
? ?#3 = Methodref ? ? ? ? ?#2.#45 ? ? ? ? // CctvTest."<init>":()V
? ?#4 = String ? ? ? ? ? ? #42 ? ? ? ? ? ?// hl
? ?#5 = Methodref ? ? ? ? ?#2.#47 ? ? ? ? // CctvTest.heoll:(Ljava/lang/String;)V
? ?#6 = Fieldref ? ? ? ? ? #48.#49 ? ? ? ?// java/lang/System.out:Ljava/io/PrintStream;
? ?#7 = Class ? ? ? ? ? ? ?#50 ? ? ? ? ? ?// java/lang/StringBuilder
? ?#8 = Methodref ? ? ? ? ?#7.#45 ? ? ? ? // java/lang/StringBuilder."<init>":()V
? ?#9 = String ? ? ? ? ? ? #51 ? ? ? ? ? ?// 欢迎光临
? #10 = Methodref ? ? ? ? ?#7.#52 ? ? ? ? // java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
? #11 = Methodref ? ? ? ? ?#7.#53 ? ? ? ? // java/lang/StringBuilder.toString:()Ljava/lang/String;
? #12 = Methodref ? ? ? ? ?#54.#55 ? ? ? ?// java/io/PrintStream.println:(Ljava/lang/String;)V
? #13 = Methodref ? ? ? ? ?#2.#56 ? ? ? ? // CctvTest.heoll2:(I)I
? #14 = Methodref ? ? ? ? ?#2.#57 ? ? ? ? // CctvTest.heoll3:(Ljava/lang/String;)Ljava/lang/String;
? #15 = String ? ? ? ? ? ? #58 ? ? ? ? ? ?//
? #16 = Class ? ? ? ? ? ? ?#59 ? ? ? ? ? ?// java/lang/Object
? #17 = Utf8 ? ? ? ? ? ? ? <init>
? #18 = Utf8 ? ? ? ? ? ? ? ()V
? #19 = Utf8 ? ? ? ? ? ? ? Code
? #20 = Utf8 ? ? ? ? ? ? ? LineNumberTable
? #21 = Utf8 ? ? ? ? ? ? ? LocalVariableTable
? #22 = Utf8 ? ? ? ? ? ? ? this
? #23 = Utf8 ? ? ? ? ? ? ? LCctvTest;
? #24 = Utf8 ? ? ? ? ? ? ? main
? #25 = Utf8 ? ? ? ? ? ? ? ([Ljava/lang/String;)V
? #26 = Utf8 ? ? ? ? ? ? ? args
? #27 = Utf8 ? ? ? ? ? ? ? [Ljava/lang/String;
? #28 = Utf8 ? ? ? ? ? ? ? cctvTest
? #29 = Utf8 ? ? ? ? ? ? ? z
? #30 = Utf8 ? ? ? ? ? ? ? I
? #31 = Utf8 ? ? ? ? ? ? ? heoll
? #32 = Utf8 ? ? ? ? ? ? ? (Ljava/lang/String;)V
? #33 = Utf8 ? ? ? ? ? ? ? str
? #34 = Utf8 ? ? ? ? ? ? ? Ljava/lang/String;
? #35 = Utf8 ? ? ? ? ? ? ? i
? #36 = Utf8 ? ? ? ? ? ? ? heoll2
? #37 = Utf8 ? ? ? ? ? ? ? (I)I
? #38 = Utf8 ? ? ? ? ? ? ? c
? #39 = Utf8 ? ? ? ? ? ? ? b
? #40 = Utf8 ? ? ? ? ? ? ? heoll3
? #41 = Utf8 ? ? ? ? ? ? ? (Ljava/lang/String;)Ljava/lang/String;
? #42 = Utf8 ? ? ? ? ? ? ? hl
? #43 = Utf8 ? ? ? ? ? ? ? SourceFile
? #44 = Utf8 ? ? ? ? ? ? ? CctvTest.java
? #45 = NameAndType ? ? ? ?#17:#18 ? ? ? ?// "<init>":()V
? #46 = Utf8 ? ? ? ? ? ? ? CctvTest
? #47 = NameAndType ? ? ? ?#31:#32 ? ? ? ?// heoll:(Ljava/lang/String;)V
? #48 = Class ? ? ? ? ? ? ?#60 ? ? ? ? ? ?// java/lang/System
? #49 = NameAndType ? ? ? ?#61:#62 ? ? ? ?// out:Ljava/io/PrintStream;
? #50 = Utf8 ? ? ? ? ? ? ? java/lang/StringBuilder
? #51 = Utf8 ? ? ? ? ? ? ? 欢迎光临
? #52 = NameAndType ? ? ? ?#63:#64 ? ? ? ?// append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
? #53 = NameAndType ? ? ? ?#65:#66 ? ? ? ?// toString:()Ljava/lang/String;
? #54 = Class ? ? ? ? ? ? ?#67 ? ? ? ? ? ?// java/io/PrintStream
? #55 = NameAndType ? ? ? ?#68:#32 ? ? ? ?// println:(Ljava/lang/String;)V
? #56 = NameAndType ? ? ? ?#36:#37 ? ? ? ?// heoll2:(I)I
? #57 = NameAndType ? ? ? ?#40:#41 ? ? ? ?// heoll3:(Ljava/lang/String;)Ljava/lang/String;
? #58 = Utf8
? #59 = Utf8 ? ? ? ? ? ? ? java/lang/Object
? #60 = Utf8 ? ? ? ? ? ? ? java/lang/System
? #61 = Utf8 ? ? ? ? ? ? ? out
? #62 = Utf8 ? ? ? ? ? ? ? Ljava/io/PrintStream;
? #63 = Utf8 ? ? ? ? ? ? ? append
? #64 = Utf8 ? ? ? ? ? ? ? (Ljava/lang/String;)Ljava/lang/StringBuilder;
? #65 = Utf8 ? ? ? ? ? ? ? toString
? #66 = Utf8 ? ? ? ? ? ? ? ()Ljava/lang/String;
? #67 = Utf8 ? ? ? ? ? ? ? java/io/PrintStream
? #68 = Utf8 ? ? ? ? ? ? ? println
{
?? ?//默认构造函数 <init>
? public CctvTest();?? ??? ?//方法昵称
? ? descriptor: ()V?? ??? ??? ?//参数即返回
? ? flags: ACC_PUBLIC?? ??? ?//修饰关键字
? ? Code:?? ??? ??? ??? ??? ?//字节码指令集
? ? ? //stack 操作数栈 深度
? ? ? //locals 局部变量表
? ? ? //args_size 参数个数
? ? ? stack=1, locals=1, args_size=1
? ? ? //指令下标:操作指令 ? ?运行时常量池符号引用
? ? ? ? ?0: aload_0?? ??? ??? ??? ??? ?
? ? ? ? ?1: invokespecial #1 ? ? ? ? ? ? ? ? ?// Method java/lang/Object."<init>":()V
? ? ? ? ?4: return
? ? ? LineNumberTable:?? ??? ?//java 代码行 与字节码指令行引用
? ? ? ? line 3: 0
? ? ? LocalVariableTable:?? ?//局部变量表
? ? ? ? Start ?Length ?Slot ?Name ? Signature
? ? ? ? ? ? 0 ? ? ? 5 ? ? 0 ?this ? LCctvTest;
?? ?//以下结构相同
? public static void main(java.lang.String[]);
? ? descriptor: ([Ljava/lang/String;)V
? ? flags: ACC_PUBLIC, ACC_STATIC
? ? Code:
? ? ? stack=2, locals=3, args_size=1
? ? ? ? ?0: new ? ? ? ? ? #2 ? ? ? ? ? ? ? ? ?// class CctvTest
? ? ? ? ?3: dup
? ? ? ? ?4: invokespecial #3 ? ? ? ? ? ? ? ? ?// Method "<init>":()V
? ? ? ? ?7: astore_1
? ? ? ? ?8: bipush ? ? ? ?19
? ? ? ? 10: istore_2
? ? ? ? 11: aload_1
? ? ? ? 12: ldc ? ? ? ? ? #4 ? ? ? ? ? ? ? ? ?// String hl
? ? ? ? 14: invokevirtual #5 ? ? ? ? ? ? ? ? ?// Method heoll:(Ljava/lang/String;)V
? ? ? ? 17: return
? ? ? LineNumberTable:
? ? ? ? line 5: 0
? ? ? ? line 6: 8
? ? ? ? line 7: 11
? ? ? ? line 8: 17
? ? ? LocalVariableTable:
? ? ? ? Start ?Length ?Slot ?Name ? Signature
? ? ? ? ? ? 0 ? ? ?18 ? ? 0 ?args ? [Ljava/lang/String;
? ? ? ? ? ? 8 ? ? ?10 ? ? 1 cctvTest ? LCctvTest;
? ? ? ? ? ?11 ? ? ? 7 ? ? 2 ? ? z ? I
? public void heoll(java.lang.String);
? ? descriptor: (Ljava/lang/String;)V
? ? flags: ACC_PUBLIC
? ? Code:
? ? ? stack=3, locals=3, args_size=2
? ? ? ? ?0: getstatic ? ? #6 ? ? ? ? ? ? ? ? ?// Field java/lang/System.out:Ljava/io/PrintStream;
? ? ? ? ?3: new ? ? ? ? ? #7 ? ? ? ? ? ? ? ? ?// class java/lang/StringBuilder
? ? ? ? ?6: dup
? ? ? ? ?7: invokespecial #8 ? ? ? ? ? ? ? ? ?// Method java/lang/StringBuilder."<init>":()V
? ? ? ? 10: ldc ? ? ? ? ? #9 ? ? ? ? ? ? ? ? ?// String 欢迎光临
? ? ? ? 12: invokevirtual #10 ? ? ? ? ? ? ? ? // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
? ? ? ? 15: aload_1
? ? ? ? 16: invokevirtual #10 ? ? ? ? ? ? ? ? // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
? ? ? ? 19: invokevirtual #11 ? ? ? ? ? ? ? ? // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
? ? ? ? 22: invokevirtual #12 ? ? ? ? ? ? ? ? // Method java/io/PrintStream.println:(Ljava/lang/String;)V
? ? ? ? 25: aload_0
? ? ? ? 26: bipush ? ? ? ?10
? ? ? ? 28: invokevirtual #13 ? ? ? ? ? ? ? ? // Method heoll2:(I)I
? ? ? ? 31: istore_2
? ? ? ? 32: return
? ? ? LineNumberTable:
? ? ? ? line 12: 0
? ? ? ? line 13: 25
? ? ? ? line 14: 32
? ? ? LocalVariableTable:
? ? ? ? Start ?Length ?Slot ?Name ? Signature
? ? ? ? ? ? 0 ? ? ?33 ? ? 0 ?this ? LCctvTest;
? ? ? ? ? ? 0 ? ? ?33 ? ? 1 ? str ? Ljava/lang/String;
? ? ? ? ? ?32 ? ? ? 1 ? ? 2 ? ? i ? I
? public int heoll2(int);
? ? descriptor: (I)I
? ? flags: ACC_PUBLIC
? ? Code:
? ? ? stack=2, locals=5, args_size=2
? ? ? ? ?0: iconst_1
? ? ? ? ?1: istore_2
? ? ? ? ?2: iconst_3
? ? ? ? ?3: istore_3
? ? ? ? ?4: aload_0
? ? ? ? ?5: ldc ? ? ? ? ? #4 ? ? ? ? ? ? ? ? ?// String hl
? ? ? ? ?7: invokevirtual #14 ? ? ? ? ? ? ? ? // Method heoll3:(Ljava/lang/String;)Ljava/lang/String;
? ? ? ? 10: astore ? ? ? ?4
? ? ? ? 12: iload_2
? ? ? ? 13: iload_3
? ? ? ? 14: iadd
? ? ? ? 15: iload_1
? ? ? ? 16: iadd
? ? ? ? 17: ireturn
? ? ? LineNumberTable:
? ? ? ? line 17: 0
? ? ? ? line 18: 2
? ? ? ? line 19: 4
? ? ? ? line 20: 12
? ? ? LocalVariableTable:
? ? ? ? Start ?Length ?Slot ?Name ? Signature
? ? ? ? ? ? 0 ? ? ?18 ? ? 0 ?this ? LCctvTest;
? ? ? ? ? ? 0 ? ? ?18 ? ? 1 ? ? i ? I
? ? ? ? ? ? 2 ? ? ?16 ? ? 2 ? ? c ? I
? ? ? ? ? ? 4 ? ? ?14 ? ? 3 ? ? b ? I
? ? ? ? ? ?12 ? ? ? 6 ? ? 4 ? str ? Ljava/lang/String;
? public java.lang.String heoll3(java.lang.String);
? ? descriptor: (Ljava/lang/String;)Ljava/lang/String;
? ? flags: ACC_PUBLIC
? ? Code:
? ? ? stack=2, locals=4, args_size=2
? ? ? ? ?0: iconst_1
? ? ? ? ?1: istore_2
? ? ? ? ?2: iconst_3
? ? ? ? ?3: istore_3
? ? ? ? ?4: new ? ? ? ? ? #7 ? ? ? ? ? ? ? ? ?// class java/lang/StringBuilder
? ? ? ? ?7: dup
? ? ? ? ?8: invokespecial #8 ? ? ? ? ? ? ? ? ?// Method java/lang/StringBuilder."<init>":()V
? ? ? ? 11: aload_1
? ? ? ? 12: invokevirtual #10 ? ? ? ? ? ? ? ? // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
? ? ? ? 15: ldc ? ? ? ? ? #15 ? ? ? ? ? ? ? ? // String
? ? ? ? 17: invokevirtual #10 ? ? ? ? ? ? ? ? // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
? ? ? ? 20: invokevirtual #11 ? ? ? ? ? ? ? ? // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
? ? ? ? 23: areturn
? ? ? LineNumberTable:
? ? ? ? line 25: 0
? ? ? ? line 26: 2
? ? ? ? line 27: 4
? ? ? LocalVariableTable:
? ? ? ? Start ?Length ?Slot ?Name ? Signature
? ? ? ? ? ? 0 ? ? ?24 ? ? 0 ?this ? LCctvTest;
? ? ? ? ? ? 0 ? ? ?24 ? ? 1 ? ?hl ? Ljava/lang/String;
? ? ? ? ? ? 2 ? ? ?22 ? ? 2 ? ? c ? I
? ? ? ? ? ? 4 ? ? ?20 ? ? 3 ? ? b ? I
}
SourceFile: "CctvTest.java"
后面会讲解整体的java 类执行过程就能更好的理解
执行引擎
本地方法接口
本地方法库
java 代码 执行过程
其他虚拟机
早期java 出过:
Classic VM 已淘汰
Exact VM 已淘汰
HotSpot VM 目前jdk 默认虚拟机
KVM 几乎淘汰,因为java ME 做终于移动应用方面,早期洛基亚 塞班系统上门的游戏java 就是运行在KVM 虚拟机上现在…这部分市场…还有吗…
当然还有其他虚拟机例如:
JRockit (BEA公司)后来被oracle收购,然后差不多jdk8已经完成了 HotSpot 整合
J9 VM (IBM公司)
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!