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

目录

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.mfbz.cn/a/43986.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

用i18next使你的应用国际化-Vue

ref: https://www.i18next.com/ 在vue项目中安装相关依赖: i18nexti18next-vuei18next-browser-languagedetector,用于检测用户语言 npm install i18next i18next-vue i18next-browser-languagedetector创建i18n.js文件: import i18next f…

Sony索尼CMOS图像传感器SubLVDS与SLVS-EC接口FPGA开发方案

索尼Sony公司的工业CMOS图像传感器主要有3种接口:Sub-LVDS、SLVS、SLVS-EC。 Sub-LVDS接口的CMOS主要是IMX2XX系列和IMX3XX系列的一部分型号,例如IMX250,IMX252、IMX255、IMX392、IMX304等。 SLVS与SLVS-EC接口的CMOS主要是IMX3XX系列的一部分…

听GPT 讲K8s源代码--pkg(七)

k8s项目中 pkg/kubelet/config,pkg/kubelet/configmap,pkg/kubelet/container,pkg/kubelet/cri 这几个目录处理与 kubelet 配置、ConfigMap、容器管理和容器运行时交互相关的功能。它们共同构成了 kubelet 的核心功能,使其能够在 …

AIGC书籍推荐:《生成式深度学习的数学原理》

生成式 AI 使用各种机器学习算法,从数据中学习要素,使机器能够创建全新的数字视频、图像、文本、音频或代码等内容。生成式 AI 技术在近两年取得了重大突破,产生了全球性的影响。它的发展离不开近年来生成式深度学习大模型的突破。与一般意义…

Vue组件自定义事件

v-on:xxx"" &#xff1a;绑定 this.$emit(xxx) : 触发 this.$off() : 解绑 App.vue <template><div class"app"><h1>{{msg}}</h1><!--通过父组件给子组件传递函数类型的props实现&#xff1a;子给父传递参数--><…

java 应用 cpu 过高故障排查

文章目录 一、前言二、测试代码 Test.java三、Linux 编译运行 Test.java 程序四、top 命令查看 cpu 使用情况五、查看进程下的线程详情 top -H -p 11748六、将线程 12240 的 pid 转为 16 进制 printf "0x%x\n" 12240七、jstack 查看进程的快照遗留 一、前言 前两天…

广告行业中那些趣事系列64:低成本训练一个媲美ChatGPT效果的Vicuna模型

导读&#xff1a;本文是“数据拾光者”专栏的第六十四篇文章&#xff0c;这个系列将介绍在广告行业中自然语言处理和推荐系统实践。本篇主要从理论到实践介绍低成本训练一个媲美ChatGPT效果的Vicuna模型&#xff0c;对于希望搭建自己的大语言模型并应用到实际业务场景感兴趣的小…

研发机器配网方案(针对禁止外网电脑的组网方案)

背景&#xff1a;公司是研发型小公司&#xff0c;难免会使用A某D和K某l 等国内免费软件&#xff0c;这两个是业界律师函发得最多的软件。最简单的方案是离网使用&#xff0c;但是离网使用比较麻烦的是要进行文件传输&#xff0c;需要使用U盘拷贝&#xff0c;另外研发型企业一般…

有向图的强联通分量-SCC-Tarjan算法

有向图的强联通分量(SCC)Tarjan算法 强连通分量&#xff08;Strongly Connected Components&#xff0c;SCC&#xff09;的定义是&#xff1a;极大的强连通子图。 下图中&#xff0c;子图{1,2,3,4}为一个强连通分量&#xff0c;因为顶点1,2,3,4两两可达。{5},{6}也分别是两个强…

c语言练手项目【编写天天酷跑游戏2.0】EASYX图形库的运用。代码开源,素材已打包

天天酷跑项目的开发 项目前言 项目是基于Windows&#xff0c;easyX图形库进行开发的&#xff0c; 开发环境&#xff1a;Visual Studio 2022 项目技术最低要求&#xff1a; 常量&#xff0c;变量&#xff0c;数组&#xff0c;循环&#xff0c;函数。 文章目录 天天酷跑项目的…

Hadoop概念学习(无spring集成)

Hadoop 分布式的文件存储系统 三个核心组件 但是现在已经发展到很多组件的s 或者这个图 官网地址: https://hadoop.apache.org 历史 hadoop历史可以看这个: https://zhuanlan.zhihu.com/p/54994736 优点 高可靠性&#xff1a; Hadoop 底层维护多个数据副本&#xff0c;所…

初识网络 --- 浅了解一些基础概念

文章目录 初识网络局域网与广域网 初识协议协议分层 OSI七层模型TCP/IP 四层&#xff08;五层&#xff09;模型网络传输基本流程协议报头局域网通信原理传输流程图数据包封装和分用 初识网络 在每台计算机独立的情况下&#xff1a;假设现在有三台计算机&#xff0c;每台计算机…

2024考研408-操作系统 第五章-输入输出IO管理 学习笔记

文章目录 一、I/O管理概述1.1、I/O设备的概念与分类1.1.1、什么是I/O设备&#xff1f;1.1.2、I/O设备的分类&#xff1a;按照使用特性1.1.2、I/O设备的分类&#xff1a;按传输速率分类1.1.3、I/O设备的分类&#xff1a;按照信息交换的单位分类知识点回顾与重要考点 1.2、I/O控制…

SpringBoot Redis 使用Lettuce和Jedis配置哨兵模式

Redis 从入门到精通【应用篇】之SpringBoot Redis 配置哨兵模式 Lettuce 和Jedis 文章目录 Redis 从入门到精通【应用篇】之SpringBoot Redis 配置哨兵模式 Lettuce 和Jedis前言Lettuce和Jedis区别1. 连接方式2. 线程安全性 教程如下1. Lettuce 方式配置1.1. 添加 Redis 和 Let…

【目标跟踪】1、基础知识

文章目录 一、卡尔曼滤波二、匈牙利匹配 一、卡尔曼滤波 什么是卡尔曼滤波&#xff1f;——状态估计器 卡尔曼滤波用于在包含不确定信息的系统中做出预测&#xff0c;对系统下一步要做什么进行推测&#xff0c;且会结合推测值和观测值来得到修正后的最优值卡尔曼滤波就是利用…

git 和adb

一、git 1、git的作用 git是一个版本控制系统&#xff0c;是一种记录一个或若干文件内容变化&#xff0c;以便将来查阅特定版本修订情况的系统。 我的理解就是代码管理器&#xff1a; 第一点你可将代码备份到git仓上&#xff1b; 第二点可记录的你修改记录&#xff1b; 第三点…

周训龙老兵参观广西森林安全紧急救援装备演练

7月21日上午&#xff0c;周训龙老兵参观广西紧急救援促进中心在南宁市青秀山举行森林安全紧急救援装备演练&#xff0c;多功能水罐消防车、无人救援机等先进设备轮番上阵&#xff0c;展示了广西应对突发事件的紧急救援速度和水平。广西壮族自治区应急厅不情愿参此次演练活动。 …

Python Flask构建微信小程序订餐系统 (十)

🔥 编辑会员信息 🔥 编辑会员信息可以通过点击会员列表操作,也可以点击会员信息详情点击进行操作 🔥 修改编程会员信息列表布局 🔥 修改 web/templates/member/index.html 文件,添加跳转到编辑会员信息的页面 web/templates/member/set.html 🔥 创建用于会员…

Mybatis单元测试,不使用spring

平时开发过程中需要对mybatis的Mapper类做单元测试&#xff0c;主要是验证语法是否正确&#xff0c;尤其是一些复杂的动态sql&#xff0c;一般项目都集成了spring或springboot&#xff0c;当项比较大时&#xff0c;每次单元测试启动相当慢&#xff0c;可能需要好几分钟&#xf…

OpenCV图像处理-图像分割-MeanShift

MeanShift 1. 基本概念2.代码示例 1. 基本概念 MeanShift严格说来并不是用来对图像进行分割的&#xff0c;而是在色彩层面的平滑滤波。它会中和色彩分布相近的颜色&#xff0c;平滑色彩细节&#xff0c;侵蚀掉面积较小的的颜色区域&#xff0c;它以图像上任意一点P为圆心&…