点击查看合集
JAVA语言是跨平台的语言,JVM虚拟机是跨语言的平台。JVM虚拟机并不关心字节码文件是由什么语言生成的。只有不同的语言通过编译器生成符合JVM虚拟机规范的字节码文件,JVM就能够运行。JAVA就是通过编译生成字节码文件,然后再在JVM上运行。因此JAVA语言可以一次编译到处运行。
虚拟机
虚拟机是一台虚拟计算机,是用来执行虚拟计算机指令的软件。虚拟机可以分为系统虚拟机和程序虚拟机。
如VMware就是系统虚拟机,他是对物理计算机的仿真。
Java虚拟机是程序虚拟机,他专门为执行单个计算机程序而设计,在java虚拟机中执行的指令我们称为Java字节码指令。Java技术的核心就是java虚拟机。它能够执行字节码文件,任何语言生成的字节码文件都可以共享java虚拟机带来的跨平台性、垃圾回收器,即时编译器。
java虚拟机
java虚拟机就是二进制字节码的运行环境,负责装载字节码到其内部,解释/编译为机器指令。JDK默认的虚拟机是HotSpot,采用解释器和即时编译器并存的架构。
JVM的架构模型
java编译器输入的指令基本上是基于栈的指令集架构。另一种是基于寄存器的指令集架构。
区别
基于栈式架构的特点:
1.设计和实现更简单,适用于资源受限的系统
2.避开了寄存器的分配难题:使用零地址指令方式分配
3.指令流中的指令大部分是零地址指令,其执行过程依赖于操作栈。指令集更小,编译器容易实现。
4.不需要硬件支持,可移植性更好,更好实现跨平台。
跨平台性,指令集小,指令多;性能比寄存器差。
基于寄存器架构的特点:
1.指令集架构依赖硬件,可移植性差。
2.性能优秀和执行更高效。
3.花费更少的指令去完成一项操作。
4.在大部分情况下基于寄存器架构的指令都以一地址指令,二地址指令和三地址指令为主。
JVM生命周期
启动
java虚拟机的启动是通过引导类加载器创建一个初始类来完成的,这个类是由虚拟机的具体实现指定的。
执行
程序开始时他才运行,程序结束时他就结束。执行java程序实际上是在执行一个java虚拟机的进程。
退出
1.程序执行结束
2.程序执行时遇到异常或者错误
3.操作系统出现错误
4.调用runtime类或System类的exit方法。或Runtime类的halt方法,并且java安全管理器也允许这次exit或halt操作
类加载子系统
类加载器子系统负责加载Class文件,Class文件在文件开头有特定的文件标识。类加载器只负责class文件的加载。加载的类信息存放于一块称为方法区的内存空间。除了类的信息外,方法区中还会存放运行时常量池信息,可能还包括字符串字面值和数字常量。(这部分常量信息是class文件中常量池部分的内存映射)
类加载器子系统包括三个步骤加载 链接 初始化。
加载阶段
1.通过一个类的全限定名获取定义此类的二进制字节流
2.将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构
3.在内存中生成一个代表这个类的java.lang.Class对象,作为方法区这个类的各种数据的访问入口。
jvm规范规定了只有两种类加载器引导类加载器和自定义类加载器( 所有派生于抽象ClassLoader的类加载器都划分为自定义类加载器)。自定义类加载器又包括了扩展类加载器,系统类加载器和用户自己定义的类加载器。加载器之前不是继承关系,而是一种组合/包含关系。
public class Test1 {
public static void main(String[] args) {
//获取系统类加载器
ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
System.out.println(systemClassLoader);//sun.misc.Launcher$AppClassLoader@18b4aac2
//获取扩展类加载器
ClassLoader extClassLoader = systemClassLoader.getParent();
System.out.println(extClassLoader);//sun.misc.Launcher$ExtClassLoader@1b6d3586
//获取引导类加载器
ClassLoader bootstrapClassLoader = extClassLoader.getParent();
System.out.println(bootstrapClassLoader);//null
//获取Test1类的类加载器
ClassLoader test1ClassLoader = Test1.class.getClassLoader();
System.out.println(test1ClassLoader);//sun.misc.Launcher$AppClassLoader@18b4aac2
//获取String类的类加载器
ClassLoader stringClassLoader = String.