【Java-JVM】

在学习JVM之前,先了解Java程序执行过程和Java为什么跨平台,有助于我们对JVM的理解。

Java的执行过程:

1. 编译通过Java命令,调用JDK编译器将*.java源文件编译成*.class字节码文件。

2. 执行通过java命令,调用JVM虚拟机,执行*.class字节码文件。

Java程序的跨平台原因:

1. 通用字节码文件JDK编译器在不同平台编译相同源文件的字节码文件都是相同的。

2. 不同版本JVM虚拟机不同平台执行字节码文件会用到不同的JVM虚拟机,将字节码翻译成当前平台可以执行的机器码指令。

JDK、JRE、JVM:

JDK:Java开发工具包,提供javac编译器、jheap、jconsole等监控工具。

JRE:Java运行环境,提供Class Library 核心类库+JVM。

JVM:Java虚拟机,用于运行Java应用程序。

JVM的组成结构:

JVM由JVM解释器、JIT解释编译器、类加载器、运行时数据区、垃圾回收器、本地方法库等部分组成。

1. JVM的执行方式

JVM以解释+编译混合模式,执行字节码文件。

解释执行为主,执行过程中,JVM将每个字节码文件中的每个指令,通过解释器转换成当前平台可以识别的机器码,然后交给CPU执行。

为了提高执行效率,JVM还会在运行期间,JVM通过热点代码的统计分析,识别高频的方法调用,循环体、公共模块等,当超过阈值时,JVM会基于JIT即时编译器(just-in-time compiler )将热点代码转换成机器码,直接交给CPU 执行,提高执行效率。

2. JVM类加载机制

程序主动使用某个类时,如果该类还未被加载到内存中,则JVM会通过加载、连接、初始化3个步骤来对该类进行初始化。如果没有意外,JVM将会连续完成3个步骤,所以有时也把这个3个步骤统称为类加载或类初始化。

2.1 类加载过程包含加载、验证、准备、解析和初始化。

1. 加载

这里的「加载」是「类加载」过程的一个阶段,「类加载」描述的是整个过程,「加载」仅表示「类加载」的第一阶段。

在加载阶段,JVM主要完成以下3件事:

1.通过类的完全限定名称获取定义该类的*.class 字节码文件的二进制字节流。

2.将该字节流表示的静态存储结构转换为Metaspace元空间区的运行时存储结构。

3.在内存中生成一个代表该类的Class对象,作为元空间区中该类各种数据的访问入口。

2. 验证

验证是为了确保 Class 文件的字节流中包含的信息符合当前虚拟机的要求,并且不会危害虚拟机自身的安全。如果验证到输入的字节流不符合 Class 文件格式的约束,虚拟机就会抛出一个 java.lang.VerifyError 异常或其子类异常。

验证阶段大致完成 4 个阶段的检验动作:

文件格式验证

元数据验证

字节码验证

符号引用验证

3. 准备

准备阶段是正式为类变量(static 修饰的变量)分配内存并设置类变量初始值的极端,这些变量所使用的内存都将在方法区中进行分配。注意此时进行内存分配的仅包括类变量,而不包括实例变量,实例变量将会在对象实例化时随着对象一起分配在 Java 堆中。

4. 解析

解析阶段是虚拟机将常量池内的符号引用替换为直接引用的过程

符号引用:只包含语义信息,不涉及具体实现,以一组符号来描述引用目标,是字面量;符号引用与虚拟机实现的内存布局无关,引用的目标并不一定已经加载到内存中。

直接引用:与具体实现息息相关,是直接指向目标的指针;直接引用是可以直接指向目标的指针、相对偏移量或是一个能间接定位到目标的句柄。如果有了直接引用,那引用的目标必定已经在内存中存在。

5. 初始化

初始化阶段,才真正开始执行类中定义的 Java 程序代码(或者说是字节码)

在准备阶段,变量已经赋过一次系统要求的初始值,而在初始化阶段,则根据程序员通过程序制定的主观计划去初始化类变量和其他资源。

也就是我们通常理解的赋初始值以及执行静态代码块。

2.2 类加载器

在类加载过程的加载阶段,通过类的完全限定名,获取描述类的二进制流的实现类,被称为"类加载器"。

从JVM虚拟机的角度来讲,只存在以下两种不同的类加载器:

1.启动类加载器(Bootstrap ClassLoader ),使用C++实现,是虚拟机的一部分;

2.其它类的加载器,使用Java实现,独立于虚拟机,继承自抽象类java.lang.classLoader。

从Java开发人员的角度可以分为:

1.启动类加载器(Bootstrap ClassLoader):负责将存放在 <JAVA_HOME>\lib 目录中的,或者被 -Xbootclasspath 参数所指定的路径中的,并且是虚拟机识别的(仅按文件名识别,如 rt.jar,名字不符合的类库即使放在 lib 目录中也不会被加载)类库加载到虚拟机内存中。

2.扩展类加载器(Extension ClassLoader):负责加载 <JAVA_HOME>\lib\ext 目录中的,或者被 java.ext.dirs 系统变量所指定的路径中的所有类库。

3.应用程序类加载器(Application ClassLoader):也称为系统类加载器,负责加载用户类路径(ClassPath)上所指定的类库。如果应用程序中没有自定义过自己的类加载器,一般情况下这个就是程序中默认的类加载器。

3. 运行时数据区

JVM虚拟机在执行Java程序的过程中会把它管理的内存划分成若干个不同的数据区域。由方法区、堆区、虚拟机栈、本地方法栈、程序计数器务部分。

JDK 1.8之前分为:线程共享(Heap堆区、Method Area方法区),线程私有(虚拟机栈、本地方法栈、程序计数器)

JDK 1.8之后分为:线程共享(Heap 堆区、MetaSpace 元空间),线程私有(虚拟机栈、本地方法栈、程序计数器)

4. JVM垃圾收集器

分类:

1.按照执行原理分类:

单线程收集器:

Serial垃圾收集器

Serial Old垃圾收集器

多线程收集器:

ParNew垃圾收集器

Parallel Scavenge垃圾收集器

Parallerl Old垃圾收集器

并发收集器:

CMS收集器

G1收集器

2.按照作用区域分类:

新生代:

Serial垃圾收集器

Parallel Scavenge垃圾收集器

ParNew垃圾收集器

老年代:

Serial Old垃圾收集器

Parallerl Old垃圾收集器

CMS收集器

整个Java堆:

G1收集器

具体介绍:

1.Serial垃圾收集器

定义:用于新生代,是单线程收集器,使用复制算法

缺点:单线程完成垃圾回收,在进行垃圾回收时,必须暂停其他所有工作线程,直到垃圾收集结束

2.Serial Old垃圾收集器

定义:用于老年代,是单线程收集器,使用标记整理算法

用途:jdk5.0之前版本与新生代Parallerl Scavenge收集器搭配使用

在老年代中作为CMS收集器的后备垃圾收集方案

3.ParNew垃圾收集器

定义:多线程收集器,使用复制算法,是JVM在Server模式下新生代的默认垃圾回收器

缺点:和Serial一样,多线程进行垃圾回收时也要暂停其他所有工作线程

4.Parallerl Scavenge收集器

定义:多线程垃圾收集器,使用复制算法,用于新生代中

优点:使得程序达到一个可控的吞吐量,高吞吐量能够最高效率利用CPU时间;采用自适应调节策略

5.Parallel Old收集器

定义:用于老年代,使用标记整理算法,是多线程垃圾收集器

用处:能够在老年代提供吞吐量优先的垃圾收集器

6.CMS收集器

定义:CMS(Concurrent mark sweep),用于老年代的多线程垃圾收集器,使用标记清除算法,属于并发执行的垃圾收集器

作用:获取最短垃圾回收停顿时间,从而提高用户体验

过程:

初始标记:标记GC Roots能直接管理的对象,需要暂停所有工作线程

并发标记:进行GC Roots跟踪,和用户线程一起工作,无需暂停工作线程

重新标记:修正在并发标记期间,因用户程序工作导致标记变动的标记记录

并发清除:清楚GC Roots不可达对象,无需暂停工作线程

7.G1收集器

定义:G1(Garbage First)使用标记整理算法

优点:不会产生内存碎片

可以精确控制停顿时间,实现低停顿的垃圾回收

将整个Java堆内存划分为几个固定区域,优先回收垃圾最多的区域

相关推荐
better_liang8 分钟前
每日Java面试场景题知识点之-TCP/IP协议栈与Socket编程
java·tcp/ip·计算机网络·网络编程·socket·面试题
niucloud-admin20 分钟前
java服务端——controller控制器
java·开发语言
To Be Clean Coder21 分钟前
【Spring源码】通过 Bean 工厂获取 Bean 的过程
java·后端·spring
Fortunate Chen27 分钟前
类与对象(下)
java·javascript·jvm
程序员水自流28 分钟前
【AI大模型第9集】Function Calling,让AI大模型连接外部世界
java·人工智能·llm
‿hhh31 分钟前
综合交通运行协调与应急指挥平台项目说明
java·ajax·npm·json·需求分析·个人开发·规格说明书
小徐Chao努力31 分钟前
【Langchain4j-Java AI开发】06-工具与函数调用
java·人工智能·python
无心水34 分钟前
【神经风格迁移:全链路压测】33、全链路监控与性能优化最佳实践:Java+Python+AI系统稳定性保障的终极武器
java·python·性能优化
萧曵 丶43 分钟前
Synchronized 详解及 JDK 版本优化
java·多线程·synchronized
夏幻灵1 小时前
JAVA基础:基本数据类型和引用数据类型
java·开发语言