jvm初识 您所在的位置:网站首页 class语言 jvm初识

jvm初识

2023-08-16 04:56| 来源: 网络整理| 查看: 265

一、什么是jvm? 1.1对比物理机

物理机: 在这里插入图片描述 jvm: 在这里插入图片描述 Java虚拟机与物理机

Class文件类比输入设备CPU指令集类比输出设备JVM类比存储器、控制器、运算器等 1.2 JVM products

有哪些版本?

Oracle:HotSpot、JRockitIBM:J9 VMAli:TaobaoVMZual:Zing

最常用的目前是HotSpot,可以通过java -version命令查看

1.3 JDK JRE JVM 三者之间的关系

官网: https://docs.oracle.com/javase/8/docs/index.html 在这里插入图片描述 jre 包含了jvm,jdk 包含jdk

1.4 结合JDK看JVM 能够把Class文件翻译成不同平台的CPU指令集也是Write Once Run Anywhere的保证 在这里插入图片描述 1.5 HotSpot JVM Architecture

https://www.oracle.com/technetwork/tutorials/tutorials-1876574.html 在这里插入图片描述

二、 class file

Java源码文件、Kotlin源码文件、Groovy源码文件等都可以编译成class文件执行。

2.1 java 测试类 public class User { private Integer age; private String name = "Jack"; private Double salary = 100.0; private static String address; public void say() { System.out.println("Jack Say..."); } public static Integer calc(Integer op1, Integer op2) { op1 = 3; Integer result = op1 + op2; return result; } } 2.2 编译过程

javac User.java->User.class 在这里插入图片描述

2.3Class 文件格式

官方文档 https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html class 文件是一个16进制的文件 在这里插入图片描述

IDEA插件(BindED)——查看class文件的十六进制

文件的格式

ClassFile { u4 magic; u2 minor_version; u2 major_version; u2 constant_pool_count; cp_info constant_pool[constant_pool_count-1]; u2 access_flags; u2 this_class; u2 super_class; u2 interfaces_count; u2 interfaces[interfaces_count]; u2 fields_count; field_info fields[fields_count]; u2 methods_count; method_info methods[methods_count]; u2 attributes_count; attribute_info attributes[attributes_count]; } 2.4 文件的解析

user.class对应的16进制文件 在这里插入图片描述 对比类文件的格式,和上面16进制数据进行解析

cafebabe u4 magic 对应的就是16进制中的 cafebabe ,cafebabe 代表的是一个class类文件的表示,只要是一个class文件就一定是 cafebabe 开头

0000+0034:minor_version+major_version 16进制的34等于10进制的52,表示JDK的版本为8

0043:constant_pool_count 16进制的43等于10进制的67,表示常量池中常量的数量是66

cp_info:constant_pool[constant_pool_count-1] 字面量:文本字符串,final修饰的常量等 符号引用:类和接口的全限定名、字段名称和描述符、方法名称和描述符

The constant pool 官网: https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.4

常量的基本结构

cp_info { 2u1 tag; u1 info[]; }

在这里插入图片描述

2.5 反汇编

javap ‐v ‐c ‐p User.class > User.txt 进行反编译,查看字节码信息和指令等信息 JVM相对class文件来说可以理解为是操作系统;class文件相对JVM来说可以理解为是汇编语言或者机 器语言。

3.类加载机制

官网:https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-5.html

3.1 加载 3.3.1 4种ClassLoader

在这里插入图片描述

3.1.2 双亲委派机制 try { if (parent != null) { // 先找父加载器 c = parent.loadClass(name, false); } else { c = findBootstrapClassOrNull(name); } } catch (ClassNotFoundException e) { // ClassNotFoundException thrown if class not found // from the non-null parent class loader } 检查某个类是否已经加载 自底向上,从Custom ClassLoader到BootStrap ClassLoader逐层检查,只要某个Classloader已加载,就视为已加载此类,保证此类只所有ClassLoader加载一次。加载的顺序 自顶向下,也就是由上层来逐层尝试加载此类。 3.1.3 java代码 public class Demo { public static void main(String[] args) { // App ClassLoader System.out.println(new Demo().getClass().getClassLoader()); // Ext ClassLoader System.out.println(new Demo().getClass().getClassLoader().getParent()); // Bootstrap ClassLoader System.out.println(new Demo().getClass().getClassLoader().getParent().getParent()); } }

结果 在这里插入图片描述 bootstrap classloader 是c语言实现的打印不出来

3.1.4 破坏双亲委派 tomcat 在这里插入图片描述

(2)SPI机制 (3)OSGi

3.2Linking 3.2.1 Verification

保证被加载类的正确性

3.2.2 Preparation

为类的静态变量分配内存,并将其初始化为默认值

3.2.3 Resolution

把类中的符号引用转换为直接引用

3.3 Initialization

对类的静态变量,静态代码块执行初始化操作

04 运行时数据区

官网:https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-2.html#jvms-2.5

4.1Method Area(方法区)

JVM运行时数据区是一种规范,真正的实现在JDK 8中就是Metaspace,在JDK6或7中就是Perm Space方法区是各个线程共享的内存区域,在虚拟机启动时创建,虽然Java虚拟机规范把方法区描述为堆的一个逻辑部分,但是它却又一个别名叫做Non-Heap(非堆),目的是与Java堆区分开来。用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。当方法区无法 满足内存分配需求时,将抛出OutOfMemoryError异常。

4.1.1常量池和运行时常量池

The Constant Pool:https://docs.oracle.com/javase/specs/jvms/se17/html/jvms-4.html#jvms- 4.4 The Run-time Constant Pool:https://docs.oracle.com/javase/specs/jvms/se17/html/jvms- 2.html#jvms-2.5.5

4.1.2 String常量到底存在哪 public class SCPDemo { public static void main(String[] args) { String str1 = "jack"; // 这个常量一定会放到字符串常量池中 String str2 = "jack"; String str3=new String("Jack"); String str4=str3.intern(); // 找字符串常量池中是否有该常量,如果有就直接返回,如果没有再创建 // equals 只会比较值 == 会比较地址 System.out.println(str1.equals(str2)); // true System.out.println(str1==str2); // true System.out.println(str1.equals(str3)); // true System.out.println(str1==str3); // false

在这里插入图片描述

4.2 Heap(堆) Java堆是Java虚拟机所管理内存中最大的一块,在虚拟机启动时创建,被所有线程共享Java对象实例以及数组都在堆上分配堆内存空间不足时,也会抛出OOM 4.2.1 Java对象内存布局

一个Java对象在内存中包括3个部分:对象头、实例数据和对齐填充 在这里插入图片描述

4.2.2 方法区引用指向堆

在这里插入图片描述

4.2.3 堆指向方法区

在这里插入图片描述

4.3 Java Virtual Machine Stacks(Java虚拟机栈)

(1)虚拟机栈是一个线程执行的区域,保存着一个线程中方法的调用状态。换句话说,一个Java线程的运行状态, 由一个虚拟机栈来保存,所以虚拟机栈肯定是线程私有的,独有的,随着线程的创建而创建。 (2)每一个被线程执行的方法,为该栈中的栈帧,即每个方法对应一个栈帧。调用一个方法,就会向栈中压入一个 栈帧;一个方法调用完成,就会把该栈帧从栈中弹出。

4.3.1 代码 1 void a(){ 2 b(); 3 } 4 void b(){ 5 c(); 6 } 4.3.2 压栈出栈

在这里插入图片描述

4.3.3 Frame(栈帧)

在这里插入图片描述 在这里插入图片描述

1 public static java.lang.Integer calc(java.lang.Integer, java.lang.Integer); 2 descriptor: (Ljava/lang/Integer;Ljava/lang/Integer;)Ljava/lang/Integer; 3 flags: ACC_PUBLIC, ACC_STATIC 4 Code: 5 stack=2, locals=3, args_size=2 6 0: iconst_3 // 将int类型常量3压入[操作数栈] 7 1: invokestatic #11 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer; 8 4: astore_0 // 将int类型值存入[局部变量0] 9 5: aload_0 // 从[局部变量0]中装载int类型值入栈 10 6: invokevirtual #12 // Method java/lang/Integer.intValue:()I 11 9: aload_1 // 从[局部变量1]中装载int类型值入栈 12 10: invokevirtual #12 // Method java/lang/Integer.intValue:()I 13 13: iadd // 将栈顶元素弹出栈,执行int类型的加法,结果入栈 14 14: invokestatic #11 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer; 15 17: astore_2 // 将栈顶int类型值保存到[局部变量2]中 16 18: aload_2 // 从[局部变量2]中装载int类型值入栈 17 19: areturn // 从方法中返回int类型的数据 18 LineNumberTable: 19 line 11: 0 20 line 12: 5 21 line 13: 18 4.3.5 index为0还是1

对于Java虚拟机栈中的Local Variables,到底是从0开始还是1开始,要看当前方法是static还是实例方法。 如果是static 方法,局部变量表从0开始,实例方法,是从1开始,0留给this关键字

4.3.6栈引用指向堆

在这里插入图片描述

4.4 Native Method Stacks(本地方法栈)

在这里插入图片描述

4.5 The pc Register (程序计数器)

如果线程正在执行Java方法,则计数器记录的是正在执行的虚拟机字节码指令的地址。如果正在执行的 是Native方法,则这个计数器为空。



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有