在 Java 编程的世界里,JVM是一个至关重要的存在。如果你是一个零基础的开发者,想要深入了解 JVM,那么这篇博客将为你提供超详细的讲解。
一、什么是 JVM?
JVM(Java Virtual Machine,Java 虚拟机)是一种用于计算设备的规范,它是一个虚构出来的计算机,通过在实际的计算机上仿真模拟各种计算机功能来实现。对于 Java 语言来说,JVM 是其运行的基础。Java 程序并不是直接在操作系统上运行,而是在 JVM 上运行。JVM 屏蔽了与具体操作系统平台相关的信息,使得 Java 程序可以在不同的操作系统上实现 “一次编写,到处运行”。
二、JVM 的体系结构
(这里涉及多线程相关的知识,如果不理解可以先去了解一下多线程)
Java堆(Java Heap)是虚拟机所管理的内存中最大的一块。Java堆是被所有线程共享的一块内存区域,在虚拟机启动时创建。此内存区域的唯一目的就是存放对象实例,Java里几乎所有的对象实例都在这里分配内存
Java虚拟机栈描述的是Java方法执行的线程内存模型:方法执行时,JVM会同步创建一个栈帧,用来存储局部变量表、操作数栈、动态连接等
本地方法栈与虚拟机栈所发挥的作用是非常相似的,其区别只是虚拟机栈为虚拟机执行Java方法(也就是字节码)服务,而本地方法栈则是为虚拟机使用到的本地(Native)方法服务
方法区是比较特别的一块区域,和堆类似,它也是各个线程共享的内存区域,用于存储已被虚拟机加载的类型信息、常量、静态变量、即时编译器编译后的代码缓存等数据
程序计数器也被称为PC寄存器,是一块较小的内存空间。它可以看作是当前线程所执行的字节码的行号指示器
执行引擎就是用于执行在class中定义的指令
本地库接口用于和其他语言进行交互 , 提供和其他编程语言交互的入口
2.1 JVM 运行时数据区(面试题)
组成部分:堆、方法区、栈、本地方法栈、程序计数器(详细内容看上面)。
三、JDK、JRE和JVM的关系
JVM :英文名称(Java Virtual Machine),就是我们耳熟能详的 Java 虚拟机。它只认识 xxx.class 这种类型的文件,它能够将 class 文件中的字节码指令进行识别并调用操作系统向上的 API 完成动作。所以说,jvm 是 Java 能够跨平台的核心,具体的下文会详细说明。
JRE :英文名称(Java Runtime Environment),我们叫它:Java 运行时环境。它主要包含两个部分,jvm 的标准实现和 Java 的一些基本类库。它相对于 jvm 来说,多出来的是一部分的 Java 类库。
JDK :英文名称(Java Development Kit),Java 开发工具包。jdk 是整个 Java 开发的核心,它集成了 jre 和一些好用的小工具。例如:javac.exe,java.exe,jar.exe 等。
这三者的关系是:一层层的嵌套关系。JDK>JRE>JVM。
所以,我们再写Java代码之前,只需要下载一个jdk就能够运行代码。
四、垃圾回收机制
垃圾回收(Garbage Collection,GC)是 JVM 自动管理内存的一种机制。在 Java 程序中,程序员不需要手动管理内存,JVM 会自动回收不再使用的对象所占用的内存空间。
4.1、如何判断对象是否可回收?
引用计数法:给对象添加一个引用计数器,每当有一个地方引用它时,计数器值就加 1;当引用失效时,计数器值就减 1。当计数器值为 0 时,表示该对象没有被任何地方引用,可以被回收。但是,引用计数法存在一个问题,就是无法解决循环引用的问题。
可达性分析算法:通过一系列的称为 “GC Roots” 的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链。当一个对象到 GC Roots 没有任何引用链相连时,则证明此对象是不可用的,可以被回收。
4.2、垃圾回收算法
标记 - 清除算法:首先标记出所有需要回收的对象,然后在标记完成后统一回收所有被标记的对象。这种算法的缺点是会产生大量的内存碎片,可能会导致后续程序在运行过程中需要分配较大的连续内存空间时无法满足要求。
复制算法:将内存分为大小相等的两块,每次只使用其中的一块。当这一块内存用完了,就将还存活的对象复制到另一块内存上,然后再把已使用过的内存空间一次清理掉。这种算法的优点是实现简单,运行高效,不会产生内存碎片。但是,它的缺点是需要将内存空间一分为二,导致可用内存空间减少一半。
标记 - 整理算法:标记过程与标记 - 清除算法一样,但是在后续步骤中,不是直接对可回收对象进行清理,而是让所有存活的对象都向一端移动,然后直接清理掉端边界以外的内存。这种算法的优点是不会产生内存碎片,缺点是整理过程比较耗时。
4.3、垃圾回收器
Serial 收集器:是一个单线程的收集器,它在进行垃圾回收时,必须暂停其他所有的工作线程,直到它收集结束。
ParNew 收集器:是 Serial 收集器的多线程版本,它可以充分利用多 CPU 的优势,提高垃圾回收的效率。
Parallel Scavenge 收集器:是一个新生代收集器,它采用复制算法,目标是达到一个可控制的吞吐量。
Serial Old 收集器:是 Serial 收集器的老年代版本,它采用标记 - 整理算法。
Parallel Old 收集器:是 Parallel Scavenge 收集器的老年代版本,它采用标记 - 整理算法。
CMS(Concurrent Mark Sweep)收集器:是一种以获取最短回收停顿时间为目标的收集器,它采用标记 - 清除算法,整个过程分为四个阶段:初始标记、并发标记、重新标记和并发清除。
G1(Garbage-First)收集器:是一种面向服务端应用的垃圾收集器,它将整个 Java 堆划分为多个大小相等的独立区域(Region),在进行垃圾回收时,优先回收价值最大的 Region。
五、总结
JVM 是 Java 程序运行的基础,了解 JVM 的体系结构和垃圾回收机制对于提高 Java 程序的性能和稳定性至关重要。希望这篇博客能够帮助零基础的开发者更好地理解 JVM。
标签:Java,收集器,虚拟机,基础,回收,内存,JVM From: https://blog.csdn.net/weixin_70171141/article/details/142058345