1、何为JVM:
JVM是Java Virtual Machine(Java虚拟机)的缩写,JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。Java虚拟机包括一套字节码指令集、一组寄存器、一个栈、一个垃圾回收堆和一个存储方法域。
2、JVM的重要性
在学习java时我们能会知道java语言为什么会如此受人们爱戴,一部分原因是来自它的跨平台性,之所以跨平台是因为java笼统来说属于编译型语言(当然细致来说是:解释——编译型),编译一次后以字节码文件(.class)文件保留在机器中,JVM在解析字节码文件时,可以根据操作系统的不同而解析成相应的机器码(隐藏底层细节的特性)。Java源文件执行过程如下:
,也就是Java平台。所有的Java 程序都要在JRE下才能运行。普通用户只需要运行已开发好的java程序,安装JRE即可。
JDK(Java Development Kit)是程序开发者用来来编译、调试java程序用的开发工具包。JDK的工具也是Java程序,也需要JRE才能运行。为了保持JDK的独立性和完整性,在JDK的安装过程中,JRE也是 安装的一部分。所以,在JDK的安装目录下有一个名为jre的目录,用于存放JRE文件。
JVM(JavaVirtualMachine,Java虚拟机)是JRE的一部分。它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。JVM有自己完善的硬件架构,如处理器、堆栈、寄存器等,还具有相应的指令系统。Java语言最重要的特点就是跨平台运行。使用JVM就是为了支持与操作系统无关,实现跨平台。
图解:
4、JVM的底层原理
(1)、总体组成分为三部分:
类装载器(ClassLoader):用来装载.class文件
执行引擎:执行字节码,或者执行本地方法
运行时数据区(内存模型):方法区(元空间)、堆、java栈(线程)、PC寄存器(程序计数器)、本地方法栈
(2)、工作原理
假设一java程序如下:
方法中有自己的变量和表达式,JVM该如何去执行它们呢?
compute()栈帧内存中又分为四个部分:局部变量表、操作数栈、动态链接、方法出口。
顾名思义,局部变量表是给局部变量分配内存空间的地方,操作数栈是给变量赋值时存放数值的地方,此时JVM通过执行上示图中的指令码(出栈入栈)来完成赋值操作。
创建一个新的线程时,不仅会在栈中分配一块内存空间还分在程序计数器区中分配一块内存空间,用来记录JVM执行的位置(红色框):
程序计数器的作用:当有优先级更高的线程抢占cpu时,该线程就会被挂起,再次执行时cpu可以根据程序计数器记录的位置来承接执行。
那么谁来修改程序计数器的值及其它动作的驱动呢?就是它——字节码执行引擎(谨记组成图)
动态链接:当某个对象调用某个方法时,要在方法区找到它的位置,而动态链接就是记录所在方法区的入口位置。
方法出口:当mian方法调用并执行完compute方法时,找到方法出口记录的位置并继续执行下一条语句。
当main方法中的math对象要去调用其它方法或变量时,会先去堆中找到内存地址。说白了“堆”就是存放对象内存地址空间的。
5、JVM垃圾回收原理
垃圾回收原理时进行JVM调优的重要路径也是JVM原理的重要知识点。回收方法(算法)有:标记-整理算法、标记-清除算法、复制算法、分代收集算法。
这里具体讲一下JVM常用的“分代收集算法”。
JVM的内存可以分为堆内存和非堆内存。堆内存分为年轻代和老年代。年轻代又可以进一步划分为一个Eden(伊甸)区和两个Survivor(幸存)区组成。
(1)、JVM堆内存的分配:
JVM初始分配的堆内存由-Xms指定,默认是物理内存的1/64。JVM最大分配的堆内存由-Xmx指定,默认是物理内存的1/4。默认空余堆内存小于40%时,JVM就会增大堆直到-Xmx的最大限制。空余堆内存大于70%时,JVM会减少堆直到 -Xms的最小限制。因此我们一般设置-Xms和-Xmx相等以避免在每次GC 后调整堆的大小。
通过参数-Xmn2G 可以设置年轻代大小为2G。通过-XX:SurvivorRatio可以设置年轻代中Eden区与Survivor区的比值,设置为8,则表示年轻代中Eden区与一块Survivor的比例为8:1。注意年轻代中有两块Survivor区域。
(2)、老年代和年轻代:
长期存活的对象将进入老年代,每一次MinorGC(年轻代GC),对象年龄就大一岁,默认15岁晋升到老年代,通过
-XX:MaxTenuringThreshold设置晋升年龄。
(3)、垃圾回收方式:
Minor GC(年轻代GC):
对象优先在Eden中分配,当Eden中没有足够空间时,虚拟机将发生一次Minor GC,因为Java大多数对象都是朝生夕灭,所以Minor GC非常频繁,而且速度也很快。
Full GC(老年代GC):
Full GC是指发生在老年代的GC,当老年代没有足够的空间时即发生Full GC,发生Full GC一般都会有一次Minor GC。
(4)JVM如何判定一个对象是否应该被回收?(重点掌握)
判断一个对象是否应该被回收,主要是看其是否还有引用。判断对象是否存在引用关系的方法包括引用计数法以及root根搜索方法。