Java Virtual Machine(JVM)

JVM跨平台原理

跨平台:一次编译,到处运行
本质:不同操作系统上运行的JVM不一样,只需要把java程序编译成一份字节码文件,JVM执行不同的字节码文件。

在这里插入图片描述
Java是高级语言,提前编译一下(变成字节码文件),再执行起来就会快一点

很多高级语言,都可以编译成字节码格式。字节码可以到不同平台上运行,这也体现的字节码的跨平台效果。在这里插入图片描述

JVM整体结构

在这里插入图片描述

解释器:执行方法区中存储的字节码指令
垃圾回收器:回收垃圾对象
JIT编译器:处理一些热点的字节码指令。【字节码里可能存在一些热点指令,这些热点指令翻译过一次,就把他们缓存起来,下一次再执行热点指令,就去缓存中取。从而提高执行效率】
方法区:类加载子系统把字节码加载到方法区中
:执行过程中产生的对象
Java方法栈:当前线程执行到某个java里的方法,就会放入这里
本地方法栈:当前线程执行native方法,就会放入这里(用Java语言以外的语言编写的方法)
程序计数器:记录下一条指令的地址

类加载子系统

在这里插入图片描述

  1. 加载:把字节码文件,加载到方法区的内存空间中。

  2. 链接:(static int i = 10)

  • 验证:检查字节码文件的格式
  • 准备:先给i变量赋值为0(先赋值0
  • 解析:将符号引用解析为直接引用

符号引用可以理解为类的名字(一般由包名 + 类名确定一个类)
直接引用可以理解为这个类在方法区中对应的地址
符号引用解析为直接引用:类的名字解析为这个类在方法区对应的地址

  1. 初始化:给类里边的static属性赋值(后赋值为10

类加载器的分类

在这里插入图片描述

  1. 引导类加载器(BootStrapClassLoader)(用c++写的)
  2. 自定义类加载器(继承自ExtClassLoader 或 AppClassLoader)

ExtClassLoader 和 AppClassLoader都继承自ClassLoader类
BootStrapClassLoader:加载jre/lib目录下的类
ExtClassLoader:jre/lib/ext目录下的类
AppClassLoader:classpath(自己指定的)类加载的路径
WebAppClassLoader:Tomcat自定义的类加载器

双亲委派

作用:避免类的重复加载,防止核心API被篡改
在这里插入图片描述

当加载一个类的时候,先从应用加载器加载,这个时候应用加载器会在已加载过的库里面查看是否加载过该类,如果没有就往上调,使用父加载器,也就是扩展类加载器来加载。

  1. 先判断当前类是否被加载过
  2. 被加载过,直接返回
  3. 没有被加载过,
    • 查看AppClassLoader对象的parent属性是否为空,
    • 如果不为空,直接用parent属性加载(AppClassLoader对象的parent属性就是ExtClassLoader的对象)
    • 如果为空,则利用BootStrapClassLoader加载
      • BootStrapClassLoader如果加载到,就直接结束
      • 如果加载不到,返回ExtClassLoader,如果还是加载不到,就退回AppClassLoader,由它自己去加载当前类。

为什么Tomcat要自定义类加载器?

为了进行类的隔离,如果tomcat直接使用AppClassLoader类加载器,那么会出现以下情况:

  1. 应用A中有个com.xiaolin.Hello.class
  2. 应用B中也有个com.xiaolin.Hello.class
  3. 虽然都叫Hello.class,但是这两个类的方法、属性可能不一样
  4. 如果AppClassLoader先加载了应用A中的Hello.class文件,那么应用B就不能被加载了,因为这两个类的名字一样
  5. 所以就需要针对应用A、B设置单独的类加载器,也就是WebAppClassLoader,这样两个应用中的Hello.class都会被各自的类加载器加载到,不会产生冲突。

JVM中判断一个类是否被加载到的逻辑:类名 + 对应的类加载器实例

运行时数据区

在这里插入图片描述

方法区、堆区:多个线程共享
Java方法栈、本地方法栈、程序计数器:每个线程都有一个

程序计数器PC

是物理寄存器的抽象实现的,用来记录待执行的下一条指令的地址,是程序控制流的指示器(for、if else…都依赖它完成)。
解释器工作时,就是通过程序计数器获取下一条需要执行新的字节码指令,是JVM规范中没有规定任何OutOfMemoryError情况的区域。

虚拟机栈(Java栈、本地方法栈)

虚拟机栈是线程私有的,一个方法开始执行栈帧入栈,方法执行完后,对应的栈帧就出栈,因此不需要进行垃圾回收。

虚拟机栈存在OutOfMemoryError(内存不够)、StackOverflowError(栈溢出)

  1. 线程太多了,就可能会出现OutOfMemoryError,线程创建时没有足够的空间去创建虚拟机栈了。
  2. 方法调用的层数太多,就可能会出现StackOverflowError
    在这里插入图片描述
    栈帧:
    • 操作数栈:执行字节码指令过程中用来辅助计算的
    • 局部变量表:记录方法里的每个变量的值
      在这里插入图片描述

堆区

在这里插入图片描述
所有的对象和数组都应该存放在堆区,在执行字节码指令的时候,会把创建的对象存入堆区, 对象对应的引用地址放入虚拟机栈的栈帧中。

方法执行完之后,创建的对象不会立马被回收,而是等JVM后台执行GC后,对象才会被回收。

Eden:新对象都会先放入Eden区(除非对象的大小都超过Eden区,那么就放入老年代)
S0:也叫做from区
S1:也叫做to区
S0、S1都是用来存放MinorGC(YGC)后存在的对象
如果一个对象经过15次垃圾回收(YGC)后都没有被回收掉,那么就会被放入老年代里

默认:
新生代 : 老年代 = 1 : 2
Eden : S0区 : S1区 = 8 : 1 : 1

在这里插入图片描述
Yong GC / Minor GC:负责堆新生代进行垃圾回收
Old GC / Major GC:负责堆老年代进行垃圾回收(目前只有CMS垃圾回收器会单独对老年代进行垃圾收集,其他垃圾收集器基本都是整堆回收的时候堆老年代进行垃圾收集)
Full GC:整堆回收,也会对方法区进行垃圾收集

垃圾回收过程

为什么要进行垃圾回收?

垃圾是指在JVM中没有任何指向它的对象,如果不清理这些垃圾,他们就会一直占用内存,而不能给其他对象,最终垃圾对象会越来越多从而出现内存溢出。

如何标记垃圾对象?

  1. 引用计数器:每个对象都保存一个引用计数器属性,用户记录对象被引用的次数。
    • 优点:实现简单,计数为0表示是垃圾对象
    • 缺点:需要额外的空间来存储引用计数,需要额外的时间来维护引用计数,无法处理循环引用的问题
      在这里插入图片描述
  2. 可达性分析法:以GC Root作为起始点,然后一层一层找到所引用的对象,被找到的对象就是存活对象,其他不可达的对象就是垃圾对象。(找到可达对象)
    在这里插入图片描述

GC Root是一组引用,包括:

  • 线程中虚拟机栈 / 本地方法栈中正在执行的方法中的方法参数、局部变量所对应的对象引用
  • 方法区中保存的类的信息中的静态 / 常量属性所对应的对象引用

怎么回收垃圾对象?

  1. 标记 - 清除算法:如果可用内存不够,就会暂停用户线程的执行,然后执行算法进行垃圾回收
    • 标记阶段:从GC Roots开始遍历,找到可达对象,并在对象头中进行标记
    • 清除阶段:堆内存空间进行线性遍历,如果发现对象头中没有记录是可达,就回收他
      在这里插入图片描述

缺点:效率不高,会产生内存碎片
优点:易实现

  1. 复制算法:将内存空间分为两块,每次使用一块,进行垃圾回收时,将可达对象复制到另一块没有使用的内存中,然后再清除当前内存块中的所有对象,后续一直重复上边操作,交换着来。在这里插入图片描述

只遍历一次,如果可达就直接转移。比较适合垃圾对象比较多的场景(复制成本低、例如:新生代)
优点:没有标记和清除阶段,不会出现内存碎片
缺点:

  • 需要更多的内存,始终有一半内存空闲;
  • 对象复制后,对象存放的内存地址发生了变化,需要额外时间修改栈帧中记录的引用地址
  • 可达对象比较多,垃圾对象比较少,复制算法的效率低
  1. 标记 - 整理阶段
    • 标记阶段:标记可达对象
    • 移动阶段:将所有存活的对象移动到内存的一端
    • 整理阶段:清除边界外所有空间
      在这里插入图片描述

总结:
在这里插入图片描述
新生代中的对象存活时间比较短,可以利用复制算法(适合垃圾对象比较多的情况)

老年代中的对象存货时间比较长,可以用标记 - 清除标记 - 整理算法,比如:

  • CMS垃圾收集器采用的就是 标记 - 清除算法
  • Serial Old垃圾收集器采用的就是 标记 - 整理算法

常见的垃圾收集器

在这里插入图片描述

  1. Serial GC(新生代)和 Serial Old GC(老年代):工作线程暂停,只有一个线程进行垃圾回收
  2. Parallel GC(新生代)和 Parallel Old GC(老年代):工作线程暂停,开启多个线程进行垃圾回收
    在这里插入图片描述
  3. CMS GC(老年代):整个收集的过程更长,暂停的时间变短,而且在垃圾收集过程中大部分用户线程也还在执行,所以用户体验更好,但是吞吐量更低(单位时间内执行的用户时间更少了)
    在这里插入图片描述
  • 初始标记:暂停所有工作线程,标记处所有GC Roots能直接可达的对象,标记完后恢复工作线程。(初始标记只找到直接可达对象,不需要找到所有可达对象,只找了一层)
  • 并发标记:垃圾回收线程和用户线程一起工作,垃圾回收线程也会去剩余的可达对象(初始标记中没有找到的可达对象,但是也会存在误差)
  • 重新标记:并发标记阶段可能会产生一些误差,需要进行修正
  • 并发清理:垃圾回收线程和用户线程一起工作,删除垃圾对象(可能新生成的垃圾对象没有被清除掉)
  • 并发重置:重置一下,方便下一次垃圾回收

初始标记、并发标记、重新标记,这三个阶段都是在找垃圾对象,其实最费时的是并发标记阶段,因为这个阶段需要找出大量的垃圾对象,但是在最费时的阶段里,用户线程也在工作。

  1. G1(整堆):
    每一个方块叫做region,堆内存会分为2048个region,还是分成了Eden区、S0区、S1区、老年代,只不过空间是不连续的。
    在这里插入图片描述

Humongous区:专门用来存放大对象(一个对象的大小超过一个region的50%)

在这里插入图片描述

初始标记并发标记最终标记:同CMS
筛选回收:提前设置一个时间t(默认200ms),按照指定这个的时间t来做筛选回收(不一定会回收掉所有的垃圾)

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

duckdb导出Excel和导出CSV速度测试

运行duckdb数据库 D:>duckdb v1.2.0 5f5512b827 Enter “.help” for usage hints. Connected to a transient in-memory database. Use “.open FILENAME” to reopen on a persistent database. 生成模拟数据,10个列,100万行数据; --…

TCP/IP参考模型和网络协议

由于国防部担心他们一些重要的主机、路由器和互联网关可能会突然崩溃,所以网络必须实现的另一目标是网络不受子网硬件损失的影响,已经建立的会话不会被取消,而且整个体系结构必须相当灵活。 TCP/IP是一组用于实现网络互连的通信协议。Interne…

uniapp商场之订单模块【订单列表】

文章目录 前言一、准备静态结构(分包)二、Tabs滑动切换1.Tabs文字渲染2.点文字高亮切换3.swiper滑动切换三、Tabs页面跳转高亮四、订单列表渲染1.封装列表组件2.订单状态父传子3.封装请求API4.准备请求参数5.初始化调用6.页面渲染五、订单支付1.页面条件渲染2.事件绑定前言 …

【教程】MySQL数据库学习笔记(七)——多表操作(持续更新)

写在前面: 如果文章对你有帮助,记得点赞关注加收藏一波,利于以后需要的时候复习,多谢支持! 【MySQL数据库学习】系列文章 第一章 《认识与环境搭建》 第二章 《数据类型》 第三章 《数据定义语言DDL》 第四章 《数据操…

Mysql数据库

一.数据定义语言DDL 一.概述 DDL用于定义和管理数据库的结构 DDL关键字:1.CREATE; 2.ALTER; 3.DROP 二.SQL命名规定和规范 1.标识符命名规则 2.标识符命名规范 三.库管理 1. CREATE DATABASE 数据库名; 2. CREATE DATABASE IF NOT EXISTS 数据库名; 3. CREATE…

C++,STL容器适配器,priority_queue:优先队列深入解析

文章目录 一、容器概览与核心特性核心特性速览二、底层实现原理1. 二叉堆结构2. 容器适配器架构三、核心操作详解1. 容器初始化2. 元素操作接口3. 自定义优先队列四、实战应用场景1. 任务调度系统2. 合并K个有序链表五、性能优化策略1. 底层容器选择2. 批量建堆优化六、注意事项…

django上传文件

1、settings.py配置 # 静态文件配置 STATIC_URL /static/ STATICFILES_DIRS [BASE_DIR /static, ]上传文件 # 定义一个视图函数,该函数接收一个 request 参数 from django.shortcuts import render # 必备引入 import json from django.views.decorators.http i…

mapbox 从入门到精通 - 目录

👨‍⚕️ 主页: gis分享者 👨‍⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍⚕️ 收录于专栏:mapbox 从入门到精通 文章目录 一、🍀总目录1.1 ☘️ mapbox基础1.2 ☘️…

【Qt】:概述(下载安装、认识 QT Creator)

🌈 个人主页:Zfox_ 🔥 系列专栏:Qt 目录 一:🔥 介绍 🦋 什么是 QT🦋 QT 发展史🦋 Qt版本🦋 QT 优点 一:🔥 搭建Qt开发环境 &#x1f9…

设置mysql的主从复制模式

mysql设置主从复制模式似乎很容易,关键在于1)主库启用二进制日志,2)从库将主库设为主库。另外,主从复制,复制些什么?从我现在获得的还很少的经验来看,复制的内容有表,用户…

halo发布文章的插件问题分析

前言 在准备发文到 halo 系统的时候提示错误如下,全是乱码 尝试将 halo 插件卸载后,再将插件目录下的文件全部删除 插件目录在 C:\Users\Administrator\.vscode\extensions\halo-dev.halo-1.3.0 然后再重新安装插件,在进行初始化的时候依然…

Spring Data Neo4j

文章目录 Spring Data Neo4j简介Neo4j-OGM与SDN的区别 开发体验版本说明项目地址项目结构创建项目配置连接信息激活事务管理器创建实体类Movie类Person类ActedIn关系类 创建Dao层service层测试案例CRUD TestPersonService TestActedIn Test 执行结果查询 Spring Data Neo4j简介…

Java发展史

JavaEE的由来 语言的诞生 Java的前身是Oak语言,其目的是搞嵌入式开发开发智能面包机 叮~~~🍞🍞🍞 产品以失败告终 巅峰 网景公司需要网景浏览器打开网页,Oak->Java,进行前端开发(相关技…

怎么让DeepSeek自动化写作文案

在数字化时代,内容创作已成为企业争夺用户注意力的核心竞争力。面对海量信息需求,企业往往面临内容创作效率低下、质量参差不齐、周期长等问题。如何用技术手段解决这些痛点,成为企业迫切需要破解的难题。今天,我们将以DeepSeek为…

Mysql之主从复制

目录 1.概述 2.工作原理 3.综合案例 3.1前期准备 3.2主库配置 3.3从库配置 3.4常见问题 3.4.1主从同步出现一下错误:Slave_IO_Running: No 3.4.1主从同步出现一下错误:Slave_IO_Running: Connecting? 3.5数据测试 1.概述 MySQL的主从复制&am…

从无序到有序:上北智信通过深度数据分析改善会议室资源配置

当前企业普遍面临会议室资源管理难题,预约机制不完善和临时会议多导致资源调度不合理,既有空置又有过度拥挤现象。 针对上述问题,上北智信采用了专业数据分析手段,巧妙融合楼层平面图、环形图、折线图和柱形图等多种可视化工具&a…

使用pyCharm创建Django项目

使用pyCharm创建Django项目 1. 创建Django项目虚拟环境(最新版版本的Django) 使用pyCharm的创建项目功能,选择Django,直接创建。 2. 创建Django项目虚拟环境(安装特定版本) 2.1创建一个基础的python项目 2.2 安装指定版本的D…

RabbitMQ 在 Spring Boot中使用方式

文章目录 作用MQ docker 安装MQ使用RabbitMQ的整体架构及核心概念:RabbitMQ的整体架构及核心概念:消费者消息推送限制交换机与队列## 项目使用MQDirect: 直连模式Fanout: 广播模式Topic: 主题模式Headers: 头信息模式 使用DEMO地址异常问题记录 作用 Ra…

力扣动态规划-30【算法学习day.124】

前言 ###我做这类文章一个重要的目的还是记录自己的学习过程,我的解析也不会做的非常详细,只会提供思路和一些关键点,力扣上的大佬们的题解质量是非常非常高滴!!! 习题 1.零钱兑换 题目链接:322. 零钱兑…

AI在电竞比分网中的主要应用场景

AI在电竞体育比分网的数据应用非常广泛,能够显著提升数据分析、预测、用户体验和商业价值。以下是AI在电竞比分网中的主要应用场景: 1. 实时数据采集与分析 比赛数据实时更新:AI通过自动化系统实时采集比赛数据(如击杀数、经济差、…