【Java】JVM运行流程以及垃圾回收处理

news2024/11/22 22:14:04

目录

1.JVM简介

2.JVM 和《Java虚拟机规范》

3.JVM运行流程

1.类加载器

1.一个类的生命周期

2.双亲委派模型

2.JVM运行时数据区

1.方法区(线程共享)

JDK 1.8 元空间的变化

运行时常量池

2.堆(线程共享)

2.1演示OOM异常

3.Java虚拟机栈(线程私有)

3.本地方法栈(线程私有)

4 程序计数器(线程私有)

2.执行引擎

3.本地方法库

4.垃圾回收相关

1.死亡对象的判断算法

a) 引用计数算法

b) 可达性分析算法

 2.垃圾回收的过程(复制算法)

3.垃圾回收算法(尽量加快扫描的速度)

a) 标记-清除算法

b) 复制算法

 c) 标记-整理算法

 4.垃圾收集器

1.Serial,也就是串行执行的垃圾收集器

2.Serial Old收集器(老年代收集器,串行GC)

3.ParNew收集器(新生代收集器,并行GC)

4.Parallel Scavenge收集器(新生代收集器,并行GC) 

5.Parallel Old收集器(老年代收集器,并行GC)

6. CMS收集器(老年代收集器,并发GC)​编辑

 7.G1收集器(唯一一款全区域的垃圾回收器)


1.JVM简介

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

2.JVM 和《Java虚拟机规范》

以上的各种 JVM 版本,比如 HotSpot J9 JVM,都可以看做是不同厂商实现 JVM 产品的具体实现,而它们(JVM)产品的实现必须要符合《Java虚拟机规范》,《Java虚拟机规范》是 Oracle 发布 Java 领域最重要和最权威的著作,它完整且详细的描述了 JVM 的各个组成部分。

3.JVM运行流程

JVM是Java运行的基础,也是实现一次编译到处执行的关键,那么JVM是如何执行的呢?

程序在执行前先要把Java源代码编译成字节文件(class文件),通过一定的方式类加载子系统加载到运行时数据区中,因为字节码是JVM的一套指令集规范,操作系统并不能识别,所以要通过执行引擎将字节文件翻译成底层系统的指令再交给CPU去执行,在这个过程中有时会需要调用其它语言的接口来实现整个程序的功能

1.类加载器

1.一个类的生命周期

1.加载:是整个类加载的第一个阶段

就是读取我们的.class文件

  • 1)通过一个类的全限定名来获取定义此类的二进制字节流。
  • 2)将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构。
  • 3)在内存中生成一个代表这个类的java.lang.Class对象,作为方法区这个类的各种数据的访问入口。

2.验证:验证是连接的第一步,是为了确保class文件中的字节流符合Java虚拟机的规范

 3.准备工作

为类中的静态变量分配内存和初始值

4.解析:

将常量池中的符号引用替换为直接引用

5.初始化

初始化阶段,Java 虚拟机真正开始执行类中编写的 Java 程序代码将主导权移交给应用程序。初始化阶段就是执行类构造器方法的过程

2.双亲委派模型

如果一个类加载器收到了类加载的请求,它首先不会自己去尝试加载这个类,而是把这个请求委派给父类加载器去完成,每一个层次的类加载器都是如此,因此所有的加载请求最 终都应该传送到最顶层的启动类加载器中,只有当父加载器反馈自己无 法完成这个加载请求(它的搜索范围中没有找到所需的类)时,子加载器才会尝试自己去完成加载。
  • 启动类加载器:加载 JDK lib 目录中 Java 的核心类库,即$JAVA_HOME/lib目录。
  • 扩展类加载器。加载 lib/ext 目录下的类。
  • 应用程序类加载器:加载我们写的应用程序。
  • 自定义类加载器:根据自己的需求定制类加载器。

接收到类加载的请求-->向上逐层去询问父类是否已经加载-->到顶级父类还没有加载-->就逐层向下尝试是否能加载
优点:
1.避免类重复加载
2.保证Java核心的API不会被篡改,保证程序的安全性

虽然有优点,但在一定情况下也存在一些问题,比如Java中SPI基质中的JDBC的实现

SPI 全称 Service Provider Interface ,是 Java 提供的一套用来被第三方实现或者扩展的
接口,它可以用来启用框架扩展和替换组件。 SPI 的作用就是为这些被扩展的 API 寻找服务实现。
DriverManager 位于 rt.jar 包,由 BootStrap 类加载器加载,
而其 Driver 接口的实现类是位于服务商提供的 Jar 包中,是由子类加载器(线程上下文加载器
Thread.currentThread().getContextClassLoader )来加载的,这样就破坏了双亲委派模型了(双亲委派模型讲的是所有类都应该交给父类来加载,但 JDBC 显然并不能这样实现)。它的交互流程图如下所示:

2.JVM运行时数据区

JVM 运行时数据区域也叫内存布局,但需要注意的是它和 Java 内存模型( (Java Memory Model ,简称JMM)完全不同,属于完全不同的两个概念,它由以下 5 大部分组成:

1.方法区(线程共享)

方法区用来存储被虚拟机加载的类信息,常量,静态变量,即时编译器编译过后的代码等数据

中存放的是类对象,可以理解为对象的模板、

JDK 1.8 元空间的变化

1. 对于 HotSpot 来说,JDK 8 元空间的内存属于本地内存,这样元空间的大小就不在受 JVM 最大内存的参数影响了,而是与本地内存的大小有关。
2. JDK 8 中将字符串常量池移动到了堆中

运行时常量池

运行时常量池是方法区的一部分,存放字面量与符号引用
字面量 : 字符串 (JDK 8 移动到堆中 ) final 常量、基本数据类型的值。
符号引用 : 类和结构的完全限定名、字段的名称和描述符、方法的名称和描述符

2.堆(线程共享)

堆的作用:程序中New出来的所有对象都在保存在堆中

2.1演示OOM异常

Java堆用于存储对象实例,只要我们不断的创建对象,并且保证GC Roots到对象之间有可达路径来避免GC清除掉这些对象,那么当对象在到达最大堆容量后就会产生内存溢出异常

上面我们提到,可以使用JVM参数-Xms设置堆的最小值,-Xmx设置堆的最大值,下面我们来设置一下:

我们设置代码不停的创建新的对象,然后运行程序,发现报错了

 可以看到提示堆内存被占满了,此时我们还需要对文件进一步分析看是内存泄漏还是内存溢出

内存泄漏:泄露对象无法被GC

内存溢出:内存对象确实还应该存活,那么我们该如何修复呢?

就是在配置堆内存的时候将他调大就可以了,比如写到两千,或者检查一下对象的生命周期是否过长

3.Java虚拟机栈(线程私有)

Java虚拟机栈的生命周期和线程相同,每个线程都有对应的一个虚拟机栈,每调用一个方法都会以一个栈帧的形式加入栈中,方法执行结束后就会被调出栈

栈溢出:

栈容量只需要由- Xss参数来设置。

关于虚拟机栈会产生的两种异常:
  • 如果线程请求的栈深度大于虚拟机所允许的最大深度,会抛出StackOverFlow异常
  • 如果虚拟机在拓展栈时无法申请到足够的内存空间,则会抛出OOM异常

如果是因为多线程导致的内存溢出问题,在不能减少线程数量的情况下,只能通过减少最大堆和减少栈容量的方式来换取更多的线程

当递归调用过多时,可能就会出现栈溢出,所以我们尽量要避免

Java虚拟机栈描述的是Java方法执行的内存模型,

3.本地方法栈(线程私有)

记录的是本地方法调用的关系

4 程序计数器(线程私有)

记录当前线成的方法执行到哪一行
  • 程序计数器是一块比较小的内存空间,可以看做是当前线程所执行的字节码的行号指示器。
  • 如果当前线程正在执行的是一个Java方法,这个计数器记录的是正在执行的虚拟机字节码指令的地址:如果正在执行的是一个Native方法,这个计数器值为空

2.执行引擎

Java字节码----->CPU指令的转换过程 

针对不同的CPU使用不同的转换方式(Java语言可以跨平台的原因)

3.本地方法库

调用系统的API 

4.垃圾回收相关

1.死亡对象的判断算法

a) 引用计数算法

计数器为0的对象就是不能再被使用对象
但是最主要的原因就是引用计数法无法解决对象的循环引用问题

b) 可达性分析算法

JVM中判断对象是否死亡的算法

标记->扫描->清除

 2.垃圾回收的过程(复制算法)

 1,所有new出来的对象全都放在新生代的Eden区

2.当Eden区满了之后,会触发一次垃圾回收,然后将还存活的对象移动到s0区域

3.当Eden区再次满之后,再进行一次垃圾回收,将存活的对象全部移动到s1区域,将S1和s0区域进行交换

老年代存放满了之后,会对老年代进行一次垃圾回收

新生代放不下之后,也会放到老年代去

每次垃圾回收时,程序都会进入到暂停状态STW

3.垃圾回收算法(尽量加快扫描的速度)

a) 标记-清除算法

b) 复制算法

 c) 标记-整理算法

 4.垃圾收集器

收集算法是内存回收的方法论,那么垃圾收集器就是内存回收的具体实现

以下这些收集器是 HotSpot 虚拟机随着不同版本推出的重要的垃圾收集器JVM中一共有七种

  • 并行(Parallel) : 指多条垃圾收集线程并行工作,用户线程仍处于等待状态
  • 并发(Concurrent) : 指用户线程与垃圾收集线程同时执行(不一定并行,可能会交替执行),用户程序继续运行,而垃圾收集程序在另外一个CPU上。
  • 吞吐量:就是CPU用于运行用户代码的时间与CPU总消耗时间的比值
  • 吞 吐 量 = 运 行 用 户 代 码 时 间 / (运 行 用 户 代 码 时 间  + 垃 圾 收 集 时 间)
  • 例如:虚拟机总共运行了 100 分钟,其中垃圾收集花掉 1 分钟,那吞吐量就是 99%

    1.Serial,也就是串行执行的垃圾收集器

    2.Serial Old收集器(老年代收集器,串行GC)

3.ParNew收集器(新生代收集器,并行GC)

4.Parallel Scavenge收集器(新生代收集器,并行GC) 

5.Parallel Old收集器(老年代收集器,并行GC)

6. CMS收集器(老年代收集器,并发GC

 7.G1收集器(唯一一款全区域的垃圾回收器)

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/784545.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

王道考研数据结构--5.顺序栈

前言 日期:2023.7.25 书籍:2024年数据结构考研复习指导(王道考研系列) 内容:实现顺序栈的基本实现,主要功能如下: ❶ 栈的数据结构 ❷ 出栈 ❸ 入栈 ❹ 判栈空 ❺ 读栈顶 1.顺序栈的定义 //1.顺…

AP5216 DC-DC降恒流驱动IC LED电动摩托汽车 转向灯刹车灯雾灯驱动

产品描述 AP5216 是一款 PWM工作模式, 高效率、外围简单、内置功率管,适用于5V~100V输入的高精度降压 LED 恒流驱动芯片。输出最大功率可达9W,最大电流 1.0A。AP5216 可实现全亮/半亮功能切换,通过MODE 切换:全亮/半亮…

`MySQL`压缩包中的目录结构

MySQL压缩包中的目录结构如下: docs:存放文档和说明文件。include:存放头文件,用于在源代码中包含其他文件或库的函数、变量声明等。lib:存放库文件,包括MySQL客户端库和其他依赖库。bin:存放可执行文件,如MySQL服务器、客户端工…

jQuery入门到实战

jQuery入门到实战 😇博主简介:我是一名正在攻读研究生学位的人工智能专业学生,我可以为计算机、人工智能相关本科生和研究生提供排忧解惑的服务。如果您有任何问题或困惑,欢迎随时来交流哦!😄 ✨座右铭&…

iOS transform rotate总结

研究了一下transform的旋转设置,调了半天还以为是旋转写错了,发现是两个不同的view对象写错了,不管怎么说,还是记录一下旋转相关的操作吧。 参数都是弧度。 以一个图片来举例。 let img UIImageView.init() img.image UIImage…

计算机科学cs/电子信息ei面试准备——数学基础/线性代数复习

1. 中值定理 中值定理是反映函数与导数之间联系的重要定理,也是微积分学的理论基础,在许多方面它都有重要的作用,在进行一些公式推导与定理证明中都有很多应用。中值定理是由众多定理共同构建的,其中拉格朗日中值定理是核心&…

未来行星探索希望:新型多脚机器人-团队版

机器人正在探索一个模拟的外星环境 即使一个机器人失败了,其余的团队成员也可以抵消它的损失。 背景 虽然探测器取得了令人难以置信的发现,但它们的轮子可能会拖慢它们的速度,而不稳定的地形可能会导致损坏。虽然没有东西可以取代“毅力号”…

使用Jenkinsfile实现接口自动化测试持续集成

这里写目录标题 一、Jenkins Pipeline1、什么是流水线类型?2、流水线几个步骤: 二、用Jenkinsfile的方式去执行代码1、将jenkinsfile推送到远程仓库2、配置流水线 三、Jenkinsfile中post的使用1、背景和目的2、jenkinsfile文件编写3、构建job4、发送钉钉5、发送邮件…

周赛355(模拟、贪心、DFS+位运算+问题转化)

文章目录 周赛355[2788. 按分隔符拆分字符串](https://leetcode.cn/problems/split-strings-by-separator/)模拟(注意转义) [2789. 合并后数组中的最大元素](https://leetcode.cn/problems/largest-element-in-an-array-after-merge-operations/)贪心 [2…

Cryptopedia第4期|参与Sui生态交互,赢取SUI以及额外奖励

OKX Web3 wallet Cryptopedia第4期(Sui生态交互专场)现已正式开启。本期活动设置Cetus、MovEX、NAVI Protocol、Scallop和Typus Finance 5个DApp交互任务,用户每完成其中1个DApp交互任务并验证,即可参与抽取活动专属NFT。同时还有…

32位Cortex-M4 MCU:LPC54607J256ET180E、LPC54605J512BD100K 180MHz嵌入式微控制器

LPC546xx 32 位微控制器(MCU) 具有丰富的外设集、极低的功耗和增强的调试功能。 LPC546xx MCU系列采用ARM Cortex-M4内核,可提供以太网支持,并设有一个TFT LCD控制器和两个CAN FD模块。LPC546xx MCU旨在提高灵活性和性能可扩展性,可提供高达1…

小说小程序亲测完整版

小说小程序亲测完整版超火的微信小说小程序源码-自带采集 本套源码自带采集,拿到手的时候没有安装教程不过源码在测试的时候给大家把安装教程给补上了安装教程:PHP选择5.6以上的版本上传我们的后端解压 伪静态选择thinkphp 修改数据库链接文件config/database.php 然后我们…

小型企业使用CRM如何进行线索管理?有哪些功能?

很多小型企业面临着线索渠道单一、线索质量差、缺乏有效的跟进手段等问题。为了有效获取潜在客户,提高销售业绩,建议小型企业使用Zoho CRM系统,为您提供专业的小型企业CRM线索管理解决方案。 1、多渠道获客 CRM可以帮助企业从多个渠道触达客…

24考研数据结构-线性表4

目录 2.4.4单链表的查找操作(默认带头节点,不带头节点后续更新)2.4.4.1 按位查找操作2.4.4.2 按值查找操作2.4.4.3 求单链表的长度(带和不带头节点都写了)2.4.4.4 知识回顾与重要考点 2.4.5 单链表的创建操作2.4.5.1 头…

删除Windows顽固启动项Program

卸载软件之后可能会遇到任务管理器中启动项显示有Program这种无效项目的情况 无效项目如图所示: 解决方法 打开注册表 Win R 打开注册表后定位到 计算机\HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Run 可以直接复制粘贴到地址栏进行跳…

低版本打不开高版本CAD怎么办?教你转换CAD版本方法

转换CAD文件版本的好处是多方面的。首先,它可以确保文件格式的兼容性,从而使其可以在不同版本的CAD软件中打开和编辑。这是非常重要的,因为如果您想在不同的计算机上查看或编辑CAD文件,您可能需要使用不同版本的CAD软件。通过转换…

LLaMA2可商用|GPT-4变笨|【2023-0723】【第七期】

一、大咖观点: 傅盛:ChatGPT时代如何创业 - BOTAI - 博客园Google 已经被OpenAI 超越了吗?| AlphaGo 之父深度访谈《人民日报》:大模型的竞争,是国家科技战略的竞争WAIC 2023 | 张俊林:大语言模型带来的交…

Jmeter接口自动化生成测试报告html格式

jmeter自带执行结果查看的插件,但是需要在jmeter工具中才能查看,如果要向领导提交测试结果,不够方便直观。 笔者刚做了这方面的尝试,总结出来分享给大家。 这里需要用到ant来执行测试用例并生成HTML格式测试报告。 一、ant下载安…

Android11 相机拍照权限,以及解决resolveActivity返回null

一、配置拍照和读写权限 <uses-permission android:name"android.permission.CAMERA"/> <uses-feature android:name"android.hardware.camera" /><uses-permission android:name"android.permission.WRITE_EXTERNAL_STORAGE"/&…

swagger快速升级方案

背景 在使用SpringBoot 2.6以前去创建API文档工具一般会采用SpringFox提供的Swagger库&#xff0c;但是由于SpringBoot版本的不断升级和SpringFox摆烂不更新&#xff0c;导致了SpringBoot2.6之后的项目无法使用SpringFox去生成API文档&#xff0c;或者可以使用但是有很多的bug…