JVM(Java虚拟机)

【JVM专题】一篇文章掌握整个JVM,JVM超详细解析!!! 一文熟悉JVM 的基本概念,JVM 的运行过程,JVM 内存区域,垃圾回收与算法,JAVA 四中引用类型,JAVA IO/NIO,JVM 类加载机制等 阅读详情

一.JVM简介

JVM 是 Java Virtual Machine 的简称,意为 Java虚拟机。
虚拟机是指通过软件模拟的具有完整硬件功能的、运行在一个完全隔离的环境中的完整计算机系统。
常见的虚拟机:JVM、VMwave、Virtual Box


JVM 和其他两个虚拟机的区别:

1. VMwave与VirtualBox是通过软件模拟物理CPU的指令集,物理系统中会有很多的寄存器;
2. JVM则是通过软件模拟Java字节码的指令集,JVM中只是主要保留了PC寄存器,其他的寄存器都进行了裁剪。
JVM 是一台被定制过的现实当中不存在的计算机

 二.JVM 运行流程

程序在执行之前先要把java代码转换成字节码(class文件),JVM 首先需要把字节码通过类加载器(ClassLoader) 把文件加载到内存中 运行时数据区(Runtime Data Area) ,而字节码文件是 JVM 的一套指令集规范,并不能直接交个底层操作系统去执行,因此需要特定的命令解析器 **执行引擎(Execution Engine)**将字节码翻译成底层系统指令再交由CPU去执行,而这个过程中需要调用其他语言的接口 本地库接口(Native Interface) 来实现整个程序的功能,这就是这4个主要组成部分的职责与功能。

 三.JVM的区域划分

jvm其实是一个java进程,java进程会从操作系统这里申请一大块内存区域,给java代码使用,这一大块内存区域,进一步划分

具体怎么划分的呢? 

四个核心区域:1.程序计数器 2.元数据区(方法区jdk8之前叫法) 3.栈 4.堆

接下来逐个介绍

1.程序计数器:

很小的区域,是一种特殊的寄存器,只是用来存储当前正在执行的指令地址或下一条将要执行的指令地址(字节码指令)

2.元数据区:

 放的是类加载之后的类对象,静态变量和常量池,类元信息和方法元信息

 3.栈:

维护方法之间的调用关系和局部变量存这里,调用关系每次调用方法, 就会进入方法内部执行,当方法执行完毕,返回到调用位置,继续往后走

JVM的栈并不是操作系统直接实现的 ,而是由c++代码实现

4.堆:

new出来的对象和成员变量放这里

堆是 JVM 中最大的空间区域了,new对象,往集合类里面添加元素,成员变量等等都会放到这里
如果堆上的对象,不再使用了的话,就需要被释放掉~~(垃圾回收后面会讲到)

补充:看这样一个代码

Test t = new Test();

这个t引用变量是在栈上的还是堆上的还是在其他地方

分情况讨论:

如果 t是一个 同部变量,t就是在栈上
如果 t是一个 成员变量,t就是在堆上
如果 t是一个 静态成员变量,t 就是在元数据区

具体的JVM区域划分图

元数据区和堆,整个 java 进程共用同一份,程序计数器,和 栈,一个进程中可能有多份,(每个线程有一份) 

四.JVM类加载 

类加载简单来说就是把.class文件加载到内存,得到类对象这样的一个过程
程序员要想运行程序,就需要把程序依赖的指令和数据加载到内存中
类加载的步骤,非常复杂,但是把类加载的过程分为五个步骤

1.类加载阶段 (Loading)

加载:

a)找到 .class 文件(如何找?双亲委派模型,下面解释)
b)根据 类 的 全限定名(包名 +类名,形如 java.lang.String)
c)打开文件,读取文件内容到内存里~~

2.验证阶段(Verification)

class文件有明确的数据格式(二进制的),jvm就是要验证一下,打开读到的这个.class文件内容,是不是符合这个格式要求,要符合才能继续下一步,不符合就失败了,并且把.class的内容转化为结构化的数据

3.准备阶段(Preparation) 

类加载,最终是为了得到类对象,因此准备阶段就是给类对象分配内存空间(这个空间是未初始化的内存中的数据全是0的,类对象中的静态成员啥的也是0)
相当于我租了个写字楼,但是是毛胚房,没装修

4.解析阶段(Resolution)

针对字符串常量,进行初始化~

解析阶段是 Java 虚拟机将常量池内的符号引用(不知道自己具体地址)替换为直接引用(有了自己的地址)的过程,也就是初始化常量的过程
字符串常量,本身就包含在 .class 文件中
就需要 .class 文件里解析出来的字符串常量
放到 内存空间 里(元数据区, 常量池中)

5.初始化阶段(Initialization)

针对类对象进行初始化(初始化静态成员,执行静态代码块,对类的各种属性进行填充,如果有父类还需要加载父类…)
初始化阶段,Java 虚拟机真正开始执行类中编写的 Java 程序代码,将主导权移交给应用程序。

类加载这个动作,不是jvm一启动,就把所有的.class文件都加载了,整体是一个“懒加载”的策略(懒汉模式),非必要,不加载
什么叫做“必要”
1.创建了这个类的实例
2.使用了这个类的静态方法/静态属性
3.使用子类,会触发父类的加载

五.双亲委派模型

双亲委派模型, 描述了 类加载中,根据 全限定类名, 找到 .class 文件的过程~~

 图示↓

这一套流程,目的是为了约定"优先级,收到一个类名之后,一定是先在 标准库中找,再扩展库找
最后才是第三方库找

为啥要从applicationClassLoader开始并且一开始不会查找,直接从BootStrapClassLoader开始依次查找不行吗?

原因有两个:

1. 类加载器之间是组合关系,子加载器持有父加载器的引用,但父加载器不知道有哪些子加载器。如果从上往下找,父加载器都不知道该把请求传给谁。

2. 假设有 5 个平级的自定义类加载器,从上往下的话,Bootstrap ClassLoader 加载不了就得挨个问这 5 个子加载器,效率太低。从下往上的话,谁发起的请求最终就由谁兜底加载,路径清晰。

 补充:

 六.JVM垃圾回收(GC)

C语言中,malloc的内存必须手动free,否则就容易出现内存泄露(光申请内存,不释放,内存逐渐用完了,导致程序崩溃),于是java等后续编程语言引入了GC来解决上述问题,能够有效的减少内存泄露的出现概率


C++没有采取GC机制,是因为影响效率(cpp追求极致的效率),GC中还有一个STW(Stop The World)机制,触发大规模的GC,必须使得其他业务代码停下来=>卡了
Java在JDK17之后STW时间一般小于1ms

JVM中的内存分为好几个区域,GC主要释放的是哪个空间呢?

堆!!!(new出来的对象)

GC的工作过程 

1.找到垃圾(不再使用的对象)

一个对象,只能通过引用!!如果一个对象,没有引用指向他,此时这个对象一定是无法被使用的(妥妥的是垃圾),就释放,如果一个对象已经不想用了,但是这个引用可能还指向着呢,就不释放

如何找到垃圾?

a)引用计数法(python , php采取的这个方案)

每个对象在 new 的时候,都搭配一个小的内存空间来保存一个整数

 两个设计缺陷

内存消耗更多

尤其是对象本身比较小,引用计数消耗的空间的比例就更大
假设引用计数是 4 个字节
对象本身是 8 个字节
引用计数就相当于提高了 50% 的空间占用率

存在循环引用的情况,会导致引用计数的判定逻辑出错

b)可达性分析算法(Java采取这个方法)

把对象之间的引用关系,理解成了一个树形结构.从一些特殊的起点出发,进行遍历.只要能遍历访问到的对象,就是“可达”.再把“不可达的”当做垃圾即可

引用计数,是有空间开销,可达性分析,用时间换空间~~

流程 

 

 找到垃圾了,接下来就要释放掉垃圾

2.垃圾释放(对应的内存直接释放掉)

a)标记清除

 b)复制算法

 复制算法,解决了内存碎片问题,但是也有缺点

1.内存利用率比较低(这样最多只能同时使用一半内存)
2.如果当前的对象大部分都是要保留的,垃圾很少,此时复制成本就比较高了
用复制算法的合适场景是垃圾占大多数

c)标记整理算法

优点:解决了内存碎片问题和内存利用率问题

缺点:内存搬运数据的操作,开销是挺大的,复制成本的问题仍然还在

这么来看上述三个算法都有缺点,JVM具体采用的哪个呢?

JVM采用的是分代回收算法(把上面abc三种方法结合起来(主要是bc)扬长避短)

d)分代回收

"代"=>对象的年龄~年龄是GC的伦次,某个对象,经历一轮 GC 可达性分析之后,不是垃圾;
此时对象的年龄就 +1,初始情况就是 0

伊甸区和幸存区名字来源圣经基督,大小8:1:1(两个幸存区大小一样)

 针对不同的年龄的对象采取不同的策略
不同年龄的对象,特点是不同的~~

老年代,GC 频次就可以降低了
新生代, GC 频次就会比较高~~ 

伊甸区的对象如何到幸存区



 幸存区的如何到老年代

晋升的本质是引用更新:
JVM通过修改对象引用的地址,将其从幸存区的存活对象列表转移到老年代的内存空间中(类似“移动”而非“复制”)

老年代内存管理算法采用标记整理

  1. 空间效率:
    复制算法需要预留一半内存空间(如新生代的Survivor区),而老年代存放长期存活对象,占用空间大,浪费50%内存不现实。

  2. 对象存活率高:
    老年代的对象存活率高,复制大量存活对象性能开销大,整理开销较小。

 分代回收的过程

补充: 

 JVM内存参数也是可以修改的

  1. 堆内存设置:

    • -Xms:初始堆大小(如 -Xms512m)

    • -Xmx:最大堆大小(如 -Xmx4g)

    • -Xmn:年轻代大小(如 -Xmn2g)

    • -XX:NewRatio:老年代与年轻代的比例(如 -XX:NewRatio=2 表示老年代是年轻代的2倍)

  2. 元空间/方法区:

    • -XX:MetaspaceSize:初始元空间大小

    • -XX:MaxMetaspaceSize:最大元空间大小

  3. 直接内存:

    • -XX:MaxDirectMemorySize:直接内存大小限制

这只是内存参数,其他还有更多参数可以调,具体可以AI或百度搜索,修改教程可取抖音B站看相关视频

JVM虚拟机 JVM 阅读详情

相关推荐

Java 虚拟机(JVM)是什么

Java 虚拟机(JVM)是一个全面的信息处理和分析系统,集成了各种 Java 技术和工具的系统平台,能够运行 Java 字节码,从而为 Java 程序提供一个运行环境。JVM 是一个虚构出来的计算机,它是一款软件,用来执行一系列虚拟计算机指令。大体上,虚拟机可以分为系统虚拟机和程序虚拟机。Java 虚拟机就是典型的程序虚拟机,它专门为执行单个计算机程序而设计,在 Java 虚拟机中执行的指令我们称为 Java 字节码指令。JVM 主要由类装载器、运行时数据区、执行引擎、本地接口库和本地方法库等部分组成。

百态·数智思维 | 聚焦大数据、量化与未来AI 1461

JVM(Java虚拟机)-史上最全、最详细JVM笔记

JVM的中文名称叫Java虚拟机,它是由软件技术模拟出计算机运行的一个虚拟的计算机。 JVM也充当着一个翻译官的角色,我们编写出的Java程序,是不能够被操作系统所直接识别的,这时候JVM的作用就体现出来了,它负责把我们的程序翻译给系统“听”,告诉它我们的程序需要做什么操作。

weixin_56846554的博客 3万+

Java笔记——Java虚拟机(JVM)从入门到实战_java jvm虚拟机

G1的整个堆会被划分成多个大小相等的区域,称之为区Region,区域不要求是连续的。如果所有的加载器都没加载过,就会层层向上委派查看是否加载过,如果都没加载过,就会由顶向下尝试进行加载,如果一个类加载器,发现这个类在自己的加载路径中,就会选择去加载这个类。1.可以通过调整年轻代和老年代的比例来适应不同类型的应用程序,提高内存的利用率和性能(假如用户比较多,有大量用户会在同一时段访问订单数据,如果新生代设置小,大量数据创建,会频繁发生minor GC,所以我们希望这些生命周期短的数据能在)。

a25847a的博客 1302

【JVM】JVM内存模型详解

JVM屏蔽了与操作系统平台相关的信息,使得Java程序只需要生成在Java虚拟机上运行的目标代码(字节码),就可在多种平台上不加修改的运行,这也是Java能够“一次编译,到处运行的”原因。方法区存储的内容有:类型信息(比如类全称、父类全称)、域信息(域名称、域修饰符private等)、方法信息(方法名称、方法修饰符、返回类型等)、字面量(字面量包括文本字符串、八种基本类型的值 、被声明为final的常量等)。Java虚拟机栈是当前线程在执行方法时存储所需的数据、指令、返回地址的一种栈结构(先进后出)。

Money、坤的博客 1万+

JVM性能检测工具与调优案例实战

为了验证自己的猜想,于是准备登录后台去测试下,结果在测试的过程中发现到处订单的按钮前端居然没有做点击后按钮置灰交互事件,结果按钮可以一直点,因为导出订单数据本来就非常慢,使用的人员可能发现点击后很久后页面都没反应,结果就一直点,结果就大量的请求进入到后台,堆内存产生了大量的订单对象和EXCEL对象,而且方法执行非常慢,导致这一段时间内这些对象都无法被回收,所以最终导致内存溢出。解决方式除了调整本地内存大小之外,也可以在出现此异常时进行捕获,手动触发GC(System.gc())。

悦分享 2859

[kriging](一)网上下载的kriging克里金的C++程序的初步调试

笔者在网上下载了一份克里金的C++程序,水平有限,正在逐步地调试中。 初步 克里金法现在在许多软件都已经有集成了,据笔者所知: arcgis : 看过有的arcgis培训视频里面简略介绍了里面的插值方法,有克里金。 surfer :笔者用过这个,效果很好。 gocad :听说有 landmark &jason :研究生时候用的专业的石油物探软件,里面有克里金法,万恶的开始。 pykrig...

FOREST优快云 5610

JVM——Java虚拟机架构

0. 前言 Java虚拟机(Java virtualmachine)实现了Java语言最重要的特征:即平台无关性。 平台无关性原理:编译后的Java程序(.class文件)由JVM执行。JVM屏蔽了与具体平台相关的信息,使程序可以在多种平台上不加修改地运行。Java虚拟机在执行字节码时,把字节码解释成具体平台上的机器指令执行。因此实现Java平台无关性。 1. JVM结构图 ...

关于Android开发的一些技术点总结 ╮( ̄▽ ̄”)╭ 3万+

【深大计算机网络】实验三 可靠传输机制 实验报告 附代码

【内附代码】【深大计算机网络】实验三 可靠传输机制 实验报告 附代码

m0_74268508的博客 1654

【jvm系列-01】初识虚拟机与java虚拟机

为了解决java的跨平台性问题,

zhenghuishengq的博客 9756

从SSD到UFS:3分钟搞懂存储技术进化史(含最新协议对比)

本文梳理了从SSD到UFS的存储技术演进历程,重点解析了eMMC与UFS在架构上的核心差异。UFS凭借高速串行全双工接口,实现了性能与能效的飞跃。文章还对比了最新的UFS 4.0与PCIe 5.0 SSD协议,并探讨了3D NAND、SLC缓存等底层技术,揭示了移动与PC存储技术融合的未来趋势。

weixin_29294597的博客 279

Pydoll浏览器自动化框架教程

让浏览器自动化回归本质。不再纠缠驱动兼容、不再手动处理验证码、不再因为请求和 UI 分裂而头疼。如果你经常做 Web 自动化、爬虫或者测试,不妨试试 Pydoll。也别忘了给项目点个 ⭐,让作者知道有人喜欢这个工具。👉GitHub 地址。

代码简单说 Vue、JAVA、PHP、Node.js 熟练运用,接口、架构、性能全搞定。 204

JVM学习 认识java虚拟机

学习JVM之前对它的认识: 在高级语言被计算机认知并给出响应的过程中:通常是需要将高级语言由识别它们的解释编译器将他们翻译成汇编语言文件,计算机操作系统可以通过相应的编译器识别汇编语言从而将其转换为01组合的机器指令,这些指令是可以被CPU识别并作出相应操作的。 jvm虚拟机在对比计算机操作系统层面来讲,相当于一个针对java编译与运行的环境搭建的软件。它相当于计算机操作系统层面的一个只针对与java语言的虚拟的计算机软件。它的垃圾回收算法其实与操作系统中的外部/内部碎片回收也有一定的相似性。对于一个只

m0_59588838的博客 1498

【Envi风暴】Envi5.6安装图文教程(附Envi5.6完整版下载)

【Envi风暴】Envi5.6与应用商店app store安装图文教程(附Envi5.6完整版下载)从文末网盘下载完整的ENVI5.6安装包,如下所示:双击envi56-win.exe,开始安装。将f__x64下的两个补丁文件拷贝到安装路径。将f__x86下的两个补丁文件拷贝到安装路径。

智慧空间实验室 9194

java虚拟机jvm下载_Java虚拟机(JVM)简介

java虚拟机jvm下载什么是JVM Java虚拟机(JVM)是使计算机能够运行Java程序的抽象计算机。 JVM有三个概念: 1.规格 2.实施 3.实例。 该规范是正式描述JVM实现要求的文档。 具有单一规范可确保所有实现都可互操作。 JVM实现是满足JVM规范要求的计算机程序。 JVM的实例是在进程中运行的实现,该进程执行编译为Java字节码的计算机程序。 Java运行时环境(JR...

cunhui1209的博客 1119

Qt | linux+openCV+Qt6.5.3环境搭建成功版(带例子)

opencv安装 Qt 实战举例

Qt历险记,专注Qt技术,三年医疗设备研发经验,1年机器视觉研发经验,半年柔性传感研发经验。 1885

大数据分析案例-基于决策树算法构建信用卡违约预测模型

本项目旨在使用机器学习等算法构建信用卡违约预测模型,主要应用在金融相关领域,根据用户以往的行为数据来预测是否会违约,有利于商业银行防范和化解信用卡风险,完善信用卡违约风险管理工作。本次实验通过探索性分析以及使用决策树构建信用卡违约模型,得出以下结论:1.可透支金额主要集中在0~200000之间。2.性别对于可透支金额的影响较小。3.受教育程度和婚姻状况对可透支金额的影响较大。4.决策树模型的准确率为0.88,模型效果还有待提高。

m0_64336780的博客 7574

【Java 基础(人话版)】Java 虚拟机(JVM)

它负责把 Java 代码转换成计算机能识别的机器语言,并且让不同操作系统上的 Java 程序表现一致。JVM 负责运行 Java 代码,使得 Java 具有良好的跨平台能力。,都能保证相同的 Java 代码在不同平台上运行时,结果是一致的。不同 JVM 各有特点,适用于不同的场景。只是 JVM 规范的一种实现方式,除此之外,还有。,任何公司、组织甚至个人都可以实现自己的 JVM。JVM 运行时会划分出不同的内存区域,用来存储。等不同系统,所有 JVM 只要遵循相同的。不同 JVM 适用于不同场景,例如。

qq_45729306的博客 1万+

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

Java虚拟机JVM简介与理解(一)

Java虚拟机JVM简介与理解(一)

cucgyfjklx的博客 1万+

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

Java中JVM虚拟机详解

1、 什么是JVM? JVM是Java Virtual Machine(Java虚拟机)的缩写,JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。

HuangQinJian 3万+

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

Java虚拟机(JVM 虚拟机)

所谓虚拟机,就是一台虚拟的计算机。他是一款软件,用来执行一系列虚拟计算机指令。大体上,虚拟机可以分为系统虚拟机和程序虚拟机。大名鼎鼎的 VisualBox、VMware就属于系统虚拟机。他们完全是对物理计算机的仿真。提供了一个可以运行完整操作系统的软件平台。程序虚拟机的典型代表就是Java虚拟机,它专门为执行单个计算机程序而设计,在Java虚拟机中执行的指令我们称为Java字节码指令。

m0_74201628的博客 964

java虚拟机jvm

java虚拟机jvm -生命周期结束 1.执行System.exit()方法 2.程序正常执行结束 3.程序在执行过程中遇到异常或因错误而抛异常终止 4.由于操作系统出现错误而导致java虚拟机进程终止 -执行流程 加载:查找并加载类的二进制数据 连接: 验证被加载类的正确性 准备为类的静态变量分配内存,并将其初始化为默认值 解析将类中的符号引用,转换为直接引用 初始化:为静态变量赋值正确的...

weixin_34324081的博客 227

JVM_Java虚拟机<深入理解Java虚拟机>走进JVM

由于跨平台性的设计,Java的指令都是根据栈来设计的。不同平台CPU架构不同,所以不能设计为基于寄存器的。优点是跨平台,指令集小,编译器容易实现,缺点是性能下降,实现同样的功能需要更多的指令。时至今日,尽管嵌入式平台已经不是Java程序的主流运行平台了(准确来说应该是HotSpotVM的宿主环境已经不局限于嵌入式平台了),那么为什么不将架构更换为基于寄存器的架构呢?栈:跨平台性、指令集小、指令多、执行性能比寄存器差言包括:Java、Scala、Groovy、Kotlin;

Coastlise的博客 1168

【JVM】JAVA虚拟机总结(一)——什么是JVM

前言:Java语言里负责解释执行字节码文件的是Java虚拟机,即JVM——Java Virtual Machine(Java虚拟机)。执行Java程序的两个步骤:由Java语言编写的程序需要进过编译步骤,但这个编译步骤并不会生成特定平台的机器码,而是生成一种与平台无关的字节码(*.class文件)。这种字节码不是可执行的,必须使用Java解释器来解释执行。所有Java语言既不是纯粹的编译型语言,也...

一路向前! 4746

Java虚拟机 (JVM)(1) —— 初识JVM

Java虚拟机的启动是通过引导类加载器(bootstrap class loader)创建一个初始类(initial class)来完成的,这个类是由虚拟机的具体实现指定的。JVM是java虚拟机,是整个java实现跨平台的最核心的部分,能够运行以Java语言写作的软件程序。

知唔猪的博客 1025
上一篇: 网络层(IP协议) && 数据链路层(以太网)
下一篇: OpenClaw保姆级安装与常见问题解决(MAC&WIN)
刘 大 望
博客等级 码龄2年 896粉丝 61原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值