JVM(Java Virtual Machine) Java虚拟机 本文基于HotSpot虚拟机 先附上一个我整理的思维导图
JVM是Java Virtual Machine(Java虚拟机)的缩写,JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。 引入Java语言虚拟机后,Java语言在不同平台上运行时不需要重新编译。Java语言使用Java虚拟机屏蔽了与具体平台相关的信息,使得Java语言编译程序只需生成在Java虚拟机上运行的目标代码(字节码),就可以在多种平台上不加修改地运行。
JVM主要包含三大部分:类装载器子系统,运行时数据区,执行引擎
类装载器子系统用来读取字节码文件中的类信息,将Java类转换成java.lang.Class的一个实例加载到JVM虚拟机中
运行时数据区包括五部分:方法区(元数据区),堆,JVM栈,本地方法栈,程序计数器
方法区在JDK1.8之后改名为元数据区,元数据区存储已被类加载器加载的类信息,静态变量,常量,即时编译器编译后的代码等数据.
存放对象的实例和数组.
存放局部变量,Java方法执行的内存模型. 一个功能的实现往往需要调用多个子程序,在进入某个子程序之前,会将下一个指令的地址存放到栈中,等子程序执行完毕后通过该地址回到程序中.
本地方法栈跟虚拟机栈类似,区别是本地方法栈服务于虚拟机调用native方法时,而JVM栈服务于虚拟机调用Java方法时.
相对小的一块内存空间,是唯一一个在Java虚拟机规范中没有规定任何OOM(Out Of Memory Error:内存溢出错误)情况的区域.作用可以理解为当前线程执行的字节码代码的行号指示器.但是实际上存放的是地址.如果程序执行的是一个Java方法,那么这个计数器记录的是正在执行的字节码的指定地址,如果程序执行的是一个native方法,那么计数器的值为undefined.
因为元数据区和堆是线程共享的,所以导致了它们是线程不安全的.其它的三个组件是每个线程独有的,也就是线程安全的
执行引擎包括三部分 解释器,JIT即时编译器,垃圾回收器(GC)
解释器能够快速的解释字节码,但执行却很慢 解释器的缺点就是一个方法被调用多次,每次都需要重新解释.拖慢效率
JIT即时编译器就解决了解释器的缺点,它可以对相同方法的调用进行一个类似于缓存的操作,在第二次调用的时候无需重新编译.但是对于单次调用,它的速度不如解释器. 所以HotSpot虚拟机采用解释器与编译器共存的方式,
收集并删除未引用的对象. 对于new关键字创建的对象,我们可以使用System.gc()来进行垃圾回收 对于不是new关键字创建的对象,我们可以使用finalize函数执行清理.
大家都知道,Java语言是可以跨平台的,即所谓一次编译,多处运行 但其实,跨平台的不是Java语言,而是JVM(Java虚拟机).
首先说,机器是不能直接识别Java,C等高级语言的,只能识别机器能看懂的机器语言.所以我们在让代码生效的时候,会经过多层步骤让我们写出来的高级语言转换为机器能看懂的机器语言.基本步骤如下: Java代码(xx.java)--->编译器--->字节码文件(xx.class)--->JVM--->机器语言
Java不是运行在CPU上,而是运行在JVM虚拟机上的,JVM是一样的,尽管平台的编译方式不同,但只要最后是JVM能识别的字节码文件,就可以通过JVM转变成机器语言供机器识别实现我们的代码.
启动初始化-->执行-->结束
启动通过引导类加载器(类装载器子系统)创建初始类完成.
从main方法开始,执行java程序,直到程序执行完毕
程序正常执行完毕或抛出异常,出现错误或调用exit退出方法.
如果文章中有错误的内容,还请不吝赐教!