JVM相关知识

devtools/2024/11/27 23:19:44/

Java中的JVM(Java Virtual Machine,Java虚拟机)是一个抽象的计算机,它提供了一个运行时环境来执行Java字节码。JVM的结构清晰且复杂,主要包括以下几个关键组件:
在这里插入图片描述

1. 类加载器(Class Loader)

功能:负责将Java类文件加载到内存中,并生成对应的Class对象。它是Java实现动态性和灵活性的关键之一。
加载过程:包括加载(Loading)、链接(Linking,分为验证、准备和解析三个阶段)和初始化(Initialization)三个阶段。

2. 运行时数据区域(Runtime Data Area)

在这里插入图片描述

这是JVM在执行Java程序时用于存储各种数据的内存区域,主要包括:
方法区(Method Area,在Java 8及以后被元空间取代):存储已被虚拟机加载的类的信息、常量、静态变量、即时编译器编译后的代码等数据,是线程共享的。

  • 字符串常量池:Java中用于存储字符串字面量的一个特殊区域,它位于方法区(在Java 8及之前的版本)或元空间(在Java 8及之后的版本)中。

本地方法栈(Native Method Stack):为Java虚拟机使用到的Native方法服务,与Java虚拟机栈类似,但用于执行本地方法,也是线程私有的。
虚拟机栈(Java Virtual Machine Stacks):每个Java方法在执行时都会创建一个栈帧(Stack Frame),用于存储局部变量表、操作数栈、动态链接、方法出口等信息,是线程私有的。

  • 栈帧内部名词解释

  • 局部变量表(Local Variable Table)
    局部变量表用于存储方法的局部变量和参数。这些变量在方法执行期间有效,并在方法结束时被销毁。局部变量表的大小在编译期间就确定了,因此在方法调用时会分配足够的空间来存储这些变量。每个局部变量占用一个或多个变量槽(Variable Slot),具体取决于变量的数据类型。例如,int、float等32位以内的数据类型占用一个槽,而long、double等64位的数据类型占用两个槽。

  • 操作数栈(Operand Stack)
    操作数栈用于存放方法执行过程中的操作数和中间结果。它是一个后进先出(LIFO)的数据结构,用于支持方法的计算过程。在方法执行时,指令会从操作数栈中取出操作数,执行计算、赋值等操作,然后将结果再次存入操作数栈中。每个栈帧都有一个独立的操作数栈,多个栈帧之间不共享操作数栈。

  • 动态链接(Dynamic Linking)
    动态链接用于存储方法调用过程中的符号引用和直接引用的关系。在Java中,方法的调用是通过符号引用来表示的,这些符号引用在类加载期间被解析为直接引用。动态链接就是在运行时将这些符号引用转换为直接引用的过程。它支持方法的动态调用和多态性。

  • 方法返回地址(Return Address)
    方法返回地址用于存储方法执行完成后需要返回到的调用者的地址。当方法执行完毕后,JVM会根据这个地址将控制权返回给调用者。这是实现方法调用的重要机制之一。

  • 附加信息(Additional Information)
    除了上述主要组成部分外,栈帧还可能包含一些附加信息,如方法调用者的信息、方法的访问权限、异常处理表等。这些信息用于支持方法的执行和异常处理。

Java堆(Java Heap):存储Java对象实例和数组,是Java程序运行时的动态内存区域,也是垃圾收集器管理的主要区域。堆通常分为新生代、老年代和永久代(在Java 8及以后被元空间取代)。

  • 运行时常量池(Runtime Constant Pool):每个类或接口在编译时生成一个对应的常量池表,在运行时被加载到方法区的运行时常量池中。在Java 8及以后,运行时常量池被移到了堆中。

程序计数器(Program Counter Register):存储当前线程执行的字节码指令地址,是线程私有的。
直接内存(Direct Memory):通过NIO库可以直接使用的内存,不受Java堆的限制,也不受垃圾回收的管理。

3. 执行引擎(Execution Engine)

功能:负责执行字节码,包括解释器和即时编译器(JIT)等。解释器逐条解释执行字节码,而JIT则可以将热点代码编译成机器码以提高执行效率。

4. 垃圾回收器(Garbage Collector, GC)

功能:自动管理内存,回收不再使用的对象,释放内存空间。JVM提供了多种垃圾回收算法和回收器,如标记-清除、复制、标记-整理以及分代收集等,以适应不同的应用场景和需求。

在这里插入图片描述

Minor GC默认处理机制
Minor GC主要处理新生代(Young Generation)中的垃圾回收。新生代通常包括Eden区和两个Survivor区(Survivor From和Survivor To)。以下是Minor GC默认的处理机制:

  • 标记复制算法:
    Minor GC通常使用标记复制算法。该算法首先标记出新生代中存活的对象,然后将这些对象复制到一个空闲的Survivor区或老年代中。
    复制过程完成后,原来的Eden区和Survivor区中的对象将被清空,用于下一次对象的分配。
    垃圾回收器选择:
    不同的JVM实现和版本可能选择不同的垃圾回收器作为Minor GC的默认实现。
    例如,在Java 8之前的HotSpot JVM中,Serial和Parallel垃圾回收器是常用的Minor GC实现。
    在Java 8及之后的版本中,G1(Garbage-First)垃圾回收器成为了一种流行的选择,因为它提供了更好的性能和可预测性。

Full GC默认处理机制
Full GC处理整个堆内存(包括新生代和老年代)以及方法区(在Java 8之前为永久代PermGen,之后为元空间Metaspace)中的垃圾回收。以下是Full GC默认的处理机制:

  • 标记清除或标记整理算法:
    Full GC通常使用标记清除或标记整理算法。标记清除算法首先标记出堆内存中的存活对象,然后清除未标记的对象。
    标记整理算法在标记存活对象后,还会对存活对象进行整理,以消除内存碎片。
    需要注意的是,不同的垃圾回收器可能会选择不同的算法。例如,CMS(Concurrent Mark-Sweep)垃圾回收器使用标记清除算法,而G1垃圾回收器则使用标记整理算法。
    垃圾回收器选择:
    与Minor GC类似,Full GC的默认实现也取决于JVM的具体实现和版本。
    在Java 8之前的HotSpot JVM中,CMS垃圾回收器是一种流行的Full GC实现,因为它旨在减少停顿时间。
    在Java 8及之后的版本中,G1垃圾回收器成为了默认的Full GC实现,因为它提供了更好的性能和可预测性。
    触发条件:
    Full GC的触发条件包括老年代空间不足、方法区空间不足、显式调用System.gc()方法(尽管这只是一个建议,JVM不一定会立即执行Full GC)等。
    当触发Full GC时,JVM会暂停所有应用程序线程(Stop-the-World),以对整个堆内存进行垃圾回收。

5. Java中常见垃圾收集器的执行过程

  • Serial收集器
    Serial收集器是一个单线程的垃圾收集器,它在进行垃圾收集时,会暂停所有的应用线程(Stop-The-World,简称STW),直到垃圾收集工作完成。这个过程主要分为以下几个阶段:
    标记阶段:从GC Roots出发,标记所有可达的对象。
    清除阶段:遍历堆内存,清除所有未标记的对象。

    由于Serial收集器是单线程的,因此它的垃圾收集效率相对较低,适用于内存较小、对性能要求不高的应用。

  • Parallel收集器
    Parallel收集器是一个多线程的垃圾收集器,它使用多个线程并行地进行垃圾收集,以提高垃圾收集的效率。Parallel收集器的执行过程与Serial收集器类似,但它是多线程并行的。
    年轻代收集:使用并行复制算法,将存活的对象从一个Survivor区复制到另一个Survivor区或老年代。
    老年代收集:使用并行标记-压缩算法,标记所有可达的对象,并压缩堆内存中的空闲空间。

    Parallel收集器适用于多线程、对吞吐量有较高要求的应用。

  • CMS(Concurrent Mark Sweep)收集器
    CMS收集器是一个以最小化停顿时间为目标的垃圾收集器。它采用并发标记和并发清除的方式进行垃圾回收,以减少应用程序的停顿时间。
    CMS收集器的执行过程如下:
    初始标记阶段:STW,标记GC Roots直接可达的对象。 并发标记阶段:与应用线程并发执行,标记所有可达的对象。
    重新标记阶段:STW,处理并发标记阶段产生的所有新引用,并标记这些新引用的对象。 并发清除阶段:与应用线程并发执行,清除所有未标记的对象。

    CMS收集器的优点在于能够显著降低应用程序的停顿时间,但缺点是可能会占用较多的CPU资源,并且可能会产生内存碎片。

  • G1(Garbage-First)收集器
    G1收集器是一个面向大内存、需要低停顿时间的应用的垃圾收集器。它将堆内存划分为多个大小相等的区域(Region),并优先处理垃圾最多的区域。G1收集器的执行过程如下:
    并发标记阶段:与应用线程并发执行,标记所有可达的对象,并计算每个区域的垃圾比例。
    混合回收阶段:根据设置的停顿时间和垃圾比例,选择部分年轻代区域和部分老年代区域进行回收。回收时,将存活的对象复制到其他区域,并更新指向已回收区域的对象引用。
    并发整理阶段:在必要时,对老年代进行并发整理,以减少内存碎片。

    G1收集器的优点在于能够动态调整堆内存的使用,降低停顿时间,并提供可预测的垃圾回收性能。但缺点是配置和调优相对复杂。

  • ZGC和Shenandoah收集器
    ZGC和Shenandoah收集器是Java后续版本中引入的低延迟垃圾收集器。它们采用了一些先进的技术,如染色指针、内存多重映射等,以实现极低的停顿时间。
    ZGC收集器
    ZGC收集器基于Region内存布局,不设分代,使用读屏障、染色指针和内存多重映射等技术来实现标记-整理算法。它的停顿时间可以控制在几毫秒以内。
    Shenandoah收集器
    (注意:在某些版本的JVM中可能已经被移除或替换为其他收集器)
    Shenandoah收集器也采用了类似的并发标记和整理技术,旨在提供低延迟的垃圾回收性能。


http://www.ppmy.cn/devtools/137508.html

相关文章

Redis主从架构

Redis(Remote Dictionary Server)是一个开源的、高性能的键值对存储系统,广泛应用于缓存、消息队列、实时分析等场景。为了提高系统的可用性、可靠性和读写性能,Redis提供了主从复制(Master-Slave Replication&#xf…

tomcat 文件上传 (CVE-2017-12615)

目录 1、漏洞描述 2、访问ip:port 3、漏洞利用 4、Exploit 5、修复建议 1、漏洞描述 Tomcat 是一个小型的轻量级应用服务器,在中小型系统和并发访问用户不是很多的场合下被普遍使用,是开发和调试JSP 程序的首选。 攻击者将有可能可通过…

Java设计模式笔记(一)

Java设计模式笔记(一) (23种设计模式由于篇幅较大分为两篇展示) 一、设计模式介绍 1、设计模式的目的 让程序具有更好的: 代码重用性可读性可扩展性可靠性高内聚,低耦合 2、设计模式的七大原则 单一职…

视频变音软件哪个好用?5款视频变音软件推荐

在视频制作过程中,变音功能可以为视频增添趣味性和多样性。无论你是想制作搞笑视频、配音动画,还是进行声音伪装,一款好用的视频变音软件都是必不可少的工具。那么,视频变音软件哪个好用呢?本文将为你介绍几款热门的视…

我们来学mysql -- EXPLAIN之ref(原理篇)

EXPLAIN之ref 题记**ref** 题记 书接上文《 EXPLAIN之type》2024美国大选已定,川普剑登上铁王座,在此过程中出谋划策的幕僚很重要,是他们决定了最终的执行计划在《查询成本之索引选择》中提到,explain的输出,就是优化…

anaconda pycharm 使用问题

刚开始使用这两个工具,有点混乱,今天终于明白了一点点。 首先,可以cmd进入后用conda 创建虚拟环境,用conda create --name env_name -y命令,比如我使用conda create python36 python3.6.13创建了名为python36的环境&a…

python+pytest+allure利用fix实现接口关联

我们在日常工作中如果有一个登陆接口 在查看别的b接口 我们就要频繁的 进行登陆操作 比如登陆-加入购车 登陆-查看某个模块 登陆-加入购物车 等等 如果每次都要写登陆接口 这样会产生大量冗余的代码 所以我们就可以定一个全局变量 就不需要每次都写 直接调用就可以 举个例…

Java后端如何进行文件上传和下载 —— 本地版

简介: 本文详细介绍了在Java后端进行文件上传和下载的实现方法,包括文件上传保存到本地的完整流程、文件下载的代码实现,以及如何处理文件预览、下载大小限制和运行失败的问题,并提供了完整的代码示例。 大体思路 1、文件上传 …