通过官网了解JVM

官网jdk8结构图

jdk8文档官网:https://docs.oracle.com/javase/8/docs/

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

什么是JVM

JVM是Java虚拟机,全称Java Virtual Machine。是一个抽象的计算机器,它有一个指令集并在运行时操作内存。可以将JVM想象成是一个物理机,而一个物理机必然遵循冯诺依曼计算机模型体系
请添加图片描述
物理机接收的是0101这样的组合,因此JVM接收的也是0101这样的组合,因此输入设备这里的就是0101这样形式的。而JVM中字节码文件是作为输入设备的,这样也就可以理解为什么字节码文件是二进制文件了。

Java虚拟机被移植到不同的平台上,以提供硬件和操作系统的独立性。Java平台标准版提供了Java虚拟机(VM)的两种实现:
①Java HotSpot客户端虚拟机
客户端虚拟机是通常用于客户端应用程序的平台的实现。
客户端虚拟机经过优化,可以减少启动时间和内存占用。
它可以通过使用-client启动应用程序时的命令行选项。

②Java HotSpot服务器虚拟机
服务器虚拟机是一种实现,旨在实现最高的程序执行速度,在启动时间和内存之间进行权衡。
它可以通过使用-server启动应用程序时的命令行选项。

Java HotSpot技术的一些特性是两种VM实现共有的,如下所示:

  • 自适应编译器-应用程序使用标准解释器启动,但随后在运行时对代码进行分析,以检测性能瓶颈或“热点”。Java HotSpot VMs编译代码中对性能至关重要的部分以提高性能,同时避免对很少使用的代码(大部分程序)进行不必要的编译。Java HotSpot VMs也使用自适应编译器来动态地决定如何通过内联等技术来优化编译后的代码。编译器执行的运行时分析允许它在确定哪些优化将产生最大的性能优势时消除猜测。
  • 快速内存分配和垃圾收集- Java HotSpot技术为对象提供了快速的内存分配,并提供了快速、高效、先进的垃圾收集器选择。
  • 线程同步Java编程语言允许使用多个并发的程序执行路径(称为“线程”)。Java HotSpot技术提供了一种线程处理功能,这种功能设计成可以在大型共享内存多处理器服务器中使用。

官网查看JVM规范

官网Java语言和虚拟机规范:https://docs.oracle.com/javase/specs/index.html

在这里插入图片描述
找到自己需要的Java版本
在这里插入图片描述
选择Java虚拟机规范,点HTML和PDF都可以。

Java源文件运行过程

请添加图片描述
为什么Java一次编译到处运行?
Java源文件经过Javac编译称为.class文件,编译称字节码文件之后,交给JVM去run这个.class文件,run的一个过程显然是将字节码文件交给JVM里面去进行运行和流转。

为什么要将字节码文件交给JVM去run呢?
很多生产计算机的不同厂商、不同的CPU、包括在硬件上面进行演化,演化出不同的操作系统,不同的操作系统解析可能会有差别,为了让Java源文件,能够运行在不同的机器上,所以要对不同的操作系统去做一个屏蔽,将字节码文件交给JVM去run就可以做到,这也就是为什么Java能够做到一次编译到处运行。

Java源文件经过Javac编译成字节码文件(字节码文件==>字节流文件)

javac编译Java源文件

打开一个存放Java源文件的目录,进入dos窗口,执行命令

javac .\文件名

在这里插入图片描述

编译后的的Test.class打开是这样的在这里插入图片描述

如何阅读.class文件?

首先,去官网Java语言和虚拟机规范:https://docs.oracle.com/javase/specs/index.html
在这里插入图片描述

找到自己需要的Java版本在这里插入图片描述
选择Java虚拟机规范,点HTML和PDF都可以。
第4点就是class文件格式描述:https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html
在这里插入图片描述

class文件结构格式说明
ClassFile {
    u4             magic;//字节码文件的规范,一般value是以0xCAFEBABE开头,俗称为魔术开头
    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];
}

u2,u4,u8是无符号数据类型,是2的n次方。
注意:class文件结构里的常量池是指静态常量池
常量池一般分为三类,静态常量池,运行时常量池,字符串常量池。而class文件结构这里说的常量池指的是静态常量池。
静态常量池当中存放两个东西:
1.字面量:文本;字符串;final修饰的(final修饰的不一定都为常量)
2.符号引用:类、接口、字段、方法的一些描述信息

constant_pool是一个结构表,表示在结构及其子结构中引用的各种字符串常量、类和接口名称、字段名称和其他常量。每个表项的格式由其第一个“标记”字节表示。

class文件中内容格式是什么?

使用notepad查看编译后的.class文件,需要安装进制转换插件
在这里插入图片描述

安装之后,选中进制转换
在这里插入图片描述

可以看到字节码文件格式化后是以16进制展示的,它的本质是16进制文件吗?
不是,其实是一个二进制文件,里面存放的是16进制的字节元,而它的本质是二进制文件。

javap反编译字节码文件并输出到指定文件

class文件本质是二进制文件,看起来很难受,因此Java提供了反编译技术,可以将对应的class文件反编译成汇编语言,方便我们阅读。

在当前字节码文件目录执行命令(内容随便写写就行,先掌握输出反编译的字节码文件即可,后面会具体操作),将对应的Test.class反编译成汇编语言,并输出为Test.txt文件

 javap -p -v .\Test.class >Test.txt

打开Test.txt文件
在这里插入图片描述

有了字节码文件是为了干嘛?是为了能够读取到内存中去来使用它,那么如何使用?肯定是需要提供一个数据访问的入口从而采能够进行交互,这也就是类加载机制要干的事情。

类加载机制

类加载机制:指我们将类的字节码文件所包含的数据读入内存,同时我们会生成数据的访问入口的一种特殊机制。那么我们可以得知,类加载的最终产品是数据访问入口。
请添加图片描述
那么字节码加载的方式有哪些?或者说字节码文件可以用什么方式进行加载呢?

class文件加载方式

加载.class文件的方式:

  1. 从本地系统中加载
  2. 通过网络下载.class文件。(如Web Applet,也就是我们的小程序应用)
  3. 从归档文件中加载.class文件。(归档文件,包括jar、war、zip包去提取,都是可以的)
  4. 从专有数据库中提取.class文件。(jsp中会有这样的案例,但是很少)
  5. 将Java源文件动态编译为.class文件,也就是运行时计算,即动态代理
  6. 从加密文件中获取,也就是防止.class文件被反编译从而直接获取到流转信息,因此会对文件进行加密的保护措施

思考

类加载的方式已经了解了,接下来就可以了解类加载的过程了。

汇总

JVM1:官网了解JVM;Java源文件运行过程、javac编译Java源文件、如何阅读.class文件、class文件结构格式说明、 javap反编译字节码文件;类加载机制、class文件加载方式

JVM2:类加载机制、class文件加载方式;类加载的过程:装载、链接、初始化、使用、卸载;类加载器、为什么类加载器要分层?JVM类加载机制的三种方式:全盘负责、父类委托、缓存机制;自定义类加载器

JVM3:图解类装载与运行时数据区,方法区,堆,运行时常量池,常量池分哪些?String s1 = new String创建了几个对象?初识栈帧,栈的特点,Java虚拟机栈,本地方法发栈,对象指向问题

JVM4:Java对象内存布局:对象头、实例数据、对齐填充;JOL查看Java对象信息;小端存储和大端存储,hashcode为什么用大端存储;句柄池访问对象、直接指针访问对象、指针压缩、对齐填充及排序

JVM5:JVM内存模型与运行时数据区的关系,堆为什么分区,分代年龄,Young区划分,Survivor区为什么分为S0和S1,如何理解各种GC:Partial GC、Full GC、Young GC

JVM6:JVM内存模型验证;使用visualvm查看JVM视图;Visual GC插件下载链接;模拟JVM常见错误,模拟堆内存溢出,模拟栈溢出,模拟方法区溢出

JVM7:垃圾回收是什么?从运行时数据区看垃圾回收到底回收哪块区域?垃圾回收如何去回收?垃圾回收策略,引用计数算法及循环引用问题,可达性分析算法

JVM8:引用是什么?强引用,软引用,弱引用,虚引用,ReferenceQueue引用队列;对象生命周期有哪些阶段?创建、应用、不可见、不可达、收集、终结、对象空间重分配;重写finazlie方法弊端

JVM9:STW:stop the world,什么时候会垃圾回收?垃圾收集算法:标记清除算法、标记复制算法、标记整理算法;清除算法的整理顺序:任意顺序,滑动顺序;什么是分代收集算法?

JVM10:JVM参数分类,JVM标准参数,JVM非标准参数,-X参数,-XX参数,其他参数;查看JVM参数,idea控制台输出JVM参数,单位换算;设置JVM参数的常见方式;常用JVM参数及含义

JVM11:垃圾收集器的并发和并行,Serial,Serial Old,ParNew,Parallel Scavenge,Parallel Old,源码分析CMS两种模式,CMS如何定位可达对象?

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐