JVM理论知识
一、JVM内存结构
java的内存模型主要分为5个部分,分别是:JVM堆、JVM栈、本地栈、方法区还有程序计数器,他们的用途分别是:
- JVM堆:新建的对象都会放在这里,他是JVM中所占内存最大的区域。他又分为新生区还有老年区,刚new出来的对象放在新生区,等到内存不够的时候,再转移到老年区,这里面有一系列的GC算法,在后面讲到。
- JVM栈:他是以线程为单位进行存储的,所以他只对单个线程是可见的。JVM栈是基于栈的数据结构来存储的,每一个栈内元素是一个栈帧,一个方法被调用,就生成一个栈帧,栈帧里面保存着:局部变量表、操作栈、动态链接还有方法返回地址信息。
- 本地方法栈:jvm可以调用本地方法,通过JNI方法,这个区域就是用来保存本地调用的。
- 本地方法区(Method Area):本地方法区里面有方法常量池、保存类信息、保存方法信息的数据结构,在GC过程中,这里也是永久代数据保存的地方。
- 程序计数器:就像CPU的寄存器一样,他是记录线程切换时候机器码的行号和偏移量的,等方法回调能够正常回到方法。
二、JMM内存模型
Java的内存模型决定了线程间的通信方式,JMM的模型是由主存和本地内存构成,两个线程想要正常通行需要将本地内存中的变量刷到主存中,另一个线程才能正确读取得到,这个也是volitile关键词的原理所在。
JMM模型决定了线程见的通信,由于线程内的变量首先会存储在本地内存中,如果需要线程间通信,需要写入主存中,供其他线程读取。
由于JVM在执行程序时会产生重排序,所有需要引入volitile等关键词。
三、GC算法
1.可达性算法
1.1.引用计数算法
原理:对每个对象的引用计数,引用了则+1,释放了则-1;
1.2.GC root算法
给定一个GC root的集合的引用作为根出发, 通过引用关系遍历对象图,能被遍历到的(可达到的)对象就判定为存活, 其余对象(也就是没有被遍历到的)就自然被判定为死亡。
可以做GC root的是:
- 虚拟机栈(方法)中引用的对象;
- 类变量(静态变量)引用的对象;
- 常量引用的对象;
- JNI引用的对象;
2.GC算法
- 复制算法:从根集合开始扫描,将存活的对象复制到另一块空闲的区域
- 标记-清除算法:从根集合开始扫描,将存活的对象进行标记,将未标记的空间进行清空
- 标记-压缩算法:从根集合开始扫描,将存活的对象进行标记和清除,但清除后会将存活对象移动到空闲区域
对比:基于copy的算法适用于存活对象比较多的GC场景,Mark-sweep适合存活对象较少的场景。
copy based GC算法适合存活对象少的年轻代实现,mark-sweep GC算法适合再存活对象多的老年代实现。
四、GC回收器
衡量GC的指标主要是吞吐量、暂停时间。
吞吐量就是CPU用于运行用户代码的时间与CPU总消耗时间的比值,即吞吐量 = 运行用户代码时间 /(运行用户代码时间+垃圾收集时间)。比如:虚拟机总共运行了100分钟,其中垃圾收集花掉1分钟,那吞吐量就是99%。
暂停时间是指一个时间段内应用程序线程暂停,让GC线程执行的状态。例如,GC期间100毫秒的暂停时间意味着在这100毫秒期间内没有应用程序线程是活动的。
GC回收器的种类:
(1)serial回收器:就是在GC回收的时候工作线程暂定,他是一个串行的回收器;
(2)parallel回收器:就是GC回收器是并发执行的,因此提升了GC的吞吐量,GC过程中会stop the world;
(3)CMS,他的全程是concurrent mark sweep,他的主要优势是在GC回收大多数时候不需要stop the world;
(4)G1:这个是从JDK7后推出的新的GC,在JDK1.9成为了默认的GC回收器;
1.CMS回收器
CMS是并发标记清除GC回收器件,其目标是\获取最短GC停顿时间**,比较符合大型web server项目的使用场景。其GC阶段经过4个阶段:
- 初始标记:初始标记又GC root引用的对象,该过程会引发STW;
- 并发标记:这个是不需要STW,并发标记要回收的对象;
- 重新标记:这个节点重新标记并发阶段产生的新的要回收的对象;
- 并发清除;并发清除标记的要回收的对象;
CMS总结:
- 优点:(1)并发处理效率高;(2)GC的时候不会整体停顿STW,有效降低处理时延。
- 缺点:(1)并发清理时会降低CPU性能;(2)标记-清理可能会造成大量内存碎片;(3)并发清理阶段还会产生垃圾,这种垃圾称为浮动垃圾,需要下一次GC时才能清理掉。
2.G1回收器
G1回收器会将区域划分为region,每个region可以是新生代也可以是老年代,通过控制对region的回收,做到对垃圾回收导致的STW可控。垃圾回收的阶段前3个阶段和CMS一致,只是最后一个节点需要通过混合清除来回收新生代和老年代所有的对象:
- 初始标记;标记GC root对象,需要暂停所有用户线程,该过程会引发STW;
- 并发标记;标记GC root可达的对象。
- 最终标记;标记在并发标记阶段产生的需回收对象。
- 筛选回收:对各个Region的回收成本和价值进行排序,根据用心要求的GC停顿时间来选择需要GC的Region。
G1总结:
- 优点:(1)并发处理效率高;(2)整体停顿STW的时间可控;(3)新生掉和老年代都分为逻辑上的region,通过GC的复制算法解决内存碎片的问题;
- 缺点:引入了Remembered Set来保存内存引用信息,所以增加了内存占用,所以G1一般在大内存的服务端环境使用,起步内存大小为8G。
3.对比总结
总结:
- 选择GC主要考虑的是使用场景,一般嵌入式、内存较小的选择串行GC回收器;
- 对于需求吞吐量大的常见可以选择并行GC回收器;
- 对于需要时延少的场景可以选择CMS或者G1回收器;
- CMS回收器整体更侧重增大吞吐量,G1回收器整体是平衡了降低时延和增大吞吐量的要求;
对比:
- serial GC垃圾回收器:serial GC就是串行的GC
- CMS GC垃圾回收器:CMS经过(1)初始标记;(2)并发标记;(3)重新标记;(4)并发清除;四个阶段来完成
- G1 GC垃圾回收期:G1回收会将区域划分为region,G1通过(1)初始标记;(2)并发标记;(3)最终标记;(4)筛选回收;四个阶段完成,其中阶段四可以计算每个region的耗时来权衡总耗时,来达到一个平衡。总之回收时间可控;
五、对象实例化的过程
首先我们要明白JVM的作用是什么,那就是将.class文件加载到内存,并且实例化成对象,在实例化成对象的过程中,需要有哪些操作呢?
在进入这一步之前需要一些前置知识,包括java的54种引用类型和引用在内存中的指向等:
java引用的4种类型:
(1)强引用:利用这种方式创建的对象是强应用,Object obj = new Object();这种引用在gc时候不会回收;
(2)软引用:软引用在一次gc时候不会回收,之后不一定??
(3)弱引用:弱引用在gc时候一定会被gc;
(4)虚引用:这个用的不多,所以不了解;
栈中引用指向堆中对象:
对象实例化的过程:
(1)在new一个新的对象时,想在本地方法区中找是否有对于的类元信息,有的话直接调用相应的classloader进行加载,没有的话委托给他的父级classloader进行查找,这一步主要是将字节码文件通过字节流的心事加载进来;
(2)为对象分配内存空间。由于对象是存储在堆中,而引用是存在jvm栈中,所以栈中引用需要通过指针的方式只想堆中相应对象,这一步是需要在堆和栈中为对象分配内存空间。
(3)设置默认值和初始化。每一个基本数据都有默认值,所以在这一步,需要为变量设置默认值,同时为成员变量进行初始化操作。
参考资料
- JVM内存模型(JVMMM):https://www.huaweicloud.com/zhishi/arc-12588701.html
- JVM之配置参数详解和调优总结(二):https://www.huaweicloud.com/articles/b86de23d6c3d5a161b25b1013a388d8d.html
- jstat命令查看jvm的GC情况 (以Linux为例):http://blog.itpub.net/31543790/viewspace-2657093/
- JVM的架构与知识脉络图:https://mp.weixin.qq.com/s/RxzAePMS3ZSnqUY6cj6i7Q
- 《深入理解java虚拟机》
- ClassLoader讲的不错:https://juejin.im/post/5c04892351882516e70dcc9b?utm_source=gold_browser_extension
- 参考资料:https://mp.weixin.qq.com/s?src=11×tamp=1638361551&ver=3470&signature=Gmx2ox8EgDaJsmgMjMMcQb9v87rY-5z9dx*YUJa62leRyG0FI7gXk9eU55UiHMWJ6NYs-7W8GRh2328dZ3mBCbr7O-rFCdNNwYT-8tfe*Ypw8wQ2vpTRfL2nN-28qgBx&new=1
- 弄明白CMS和G1,就靠这一篇了:https://cloud.tencent.com/developer/article/1647637
- JVM:(十六)垃圾回收器:https://blog.csdn.net/sd_960614/article/details/126900380
本文由博客一文多发平台 OpenWrite 发布!
相关文章:

JVM理论知识
一、JVM内存结构 java的内存模型主要分为5个部分,分别是:JVM堆、JVM栈、本地栈、方法区还有程序计数器,他们的用途分别是: JVM堆:新建的对象都会放在这里,他是JVM中所占内存最大的区域。他又分为新生区还…...
idea - 报错 Mybatis提示Tag name expected的问题< 小于号 无法识别
问题:Mybatis提示Tag name expected 原因: 当我们在mapper中编写sql语句的时候会发现使用"<“符号会提示一个Tag name expected。这是因为xml文件中不识别”<"符号和“&”符号。防止与xml本身的元素命名混淆,导致无法解…...

合宙Air724UG LuatOS-Air LVGL API--对象
对象 概念 在 LVGL 中,用户界面的基本构建块是对象。例如,按钮,标签,图像,列表,图表或文本区域。 属性 基本属性 所有对象类型都共享一些基本属性: Position (位置) Size (尺寸) Parent (父母…...

Java将PDF文件转为Word文档
Java将PDF文件转为Word文档 一、创建Springboot Maven项目 二、导入依赖信息 <repositories><repository><id>com.e-iceblue</id><url>https://repo.e-iceblue.cn/repository/maven-public/</url></repository></repositories&g…...

vite创建项目命令
1.第一步运行创建命令(npm) npm create vitelatest也可以使用yarn yarn create vite还可以 pnpm create vite注意的地方:首次创建的时候会出现这个 Need to install the following packages:create-vitelatest Ok to proceed? (y) 直接y就…...

解决Pandas KeyError: “None of [Index([...])] are in the [columns]“问题
🌷🍁 博主猫头虎 带您 Go to New World.✨🍁 🦄 博客首页——猫头虎的博客🎐 🐳《面试题大全专栏》 文章图文并茂🦕生动形象🦖简单易学!欢迎大家来踩踩~🌺 &a…...

前端加springboot实现Web Socket连接通讯以及测试流程(包括后端实现心跳检测)
【2023】前端加springboot实现Web Socket连接通讯(包括后端实现心跳检测) 一级目录二级目录三级目录 前言一、Web Socket 简绍1 为什么用 websocket? 二、代码实现1、前端(html)1.1、无前端向后端发送消息1.2、有前端向…...

node使用高版本的oracledb导致连接oracle的Error: NJS-138异常
异常信息如下 Error: NJS-138: connections to this database server version are not supported by node-oracledb in Thin mode 我的oracle版本是11g,之前的使用正常,今天却报错了,显示不支持thin模式,后面回退版本就可以了。...
RabbitMQ手动签收消息
RabbitMQ手动签收消息 这里讲解SpringBoot使用RabbitMQ进行有回调的用法和消费者端手动签收消息的用法。 1、pom依赖 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"h…...
Unity 3d角色展示脚本(旋转 平移 缩放)展示界面
不考虑性能 很简陋的一个功能,主要是用于角色渲染的观察用,比simplecontroller要好用一点 using System; using UnityEngine;public class CharacterViewer : MonoBehaviour {public Transform target; // 人物模型的Transformpublic float rotationSpee…...
Spring Boot 将 Word 转换为 PDF
首先,确保项目中添加了对Apache POI和Apache PDFBox的依赖。可以在你的 pom.xml 文件中添加以下依赖: <dependencies><!-- Apache POI --><dependency><groupId>org.apache.poi</groupId><artifactId>poi</arti…...

【PHP面试题82】system和exec是用来做什么的?有什么区别
文章目录 🚀一、前言,PHP中system和exec命令的作用🚀二、system()函数🚀三、exec()函数🚀四、区别和应用场景🔎4.1 使用system()函数的应用场景🔎4.2 使用exec()函数的应用场景🔎4.3…...

05-微信小程序常用组件-表单组件
05-微信小程序常用组件-表单组件 文章目录 表单组件button 按钮案例代码 form 表单案例代码 image 图片支持长按识别的码案例代码 微信小程序包含了六大组件: 视图容器、 基础内容、 导航、 表单、 互动和 导航。这些组件可以通过WXML和WXSS进行布局和样式设…...

Lucky player —— Java 项目(Spring Boot)
一、项目介绍 项目名称:lucky player 项目的主要功能:本系统主要功能为构建了一个用户分享音乐的平台,普通用户不进行登录即可收听其他用户已经发布的专辑中的音乐。 作为博主则可以在该平台上传音频,以及在线音频录制上传。音频上…...
ios 声网agora 音视频直播场景下的集成总结
文章目录 一、前言二、视频会议场景2.1 场景描述2.2 功能列表三、电商直播场景3.1 场景描述3.2 功能列表3.3 技术方案四、声网iOS SDK集成4.1 集成4.2 示例demo4.3 核心代码4.3.1 初始化4.3.2 加入频道4.3.3 切换身份4.4.4 连麦4.4 相关问题4.4.1 监听观众角色用户事件五、相关…...

mysql 、sql server 临时表、表变量、
sql server 临时表 、表变量 mysql 临时表 创建临时表 create temporary table 表名 select 字段 [,字段2…,字段n] from 表...

15. Canvas制作汽车油耗仪表盘
1. 说明 本篇文章在14. 利用Canvas组件制作时钟的基础上进行一些更改,想查看全面的代码可以点击链接查看即可。 效果展示: 2. 整体代码 import QtQuick 2.15 import QtQuick.Controls 2.15Item{id:rootimplicitWidth: 400implicitHeight: implicitWi…...

解决git上传远程仓库时的最大文件大小限制
git默认限制最大的单文件100M,当某个文件到达50M时会给你提示。解决办法如下 首先,打开终端,进入项目所在的文件夹; 输入命令:git config http.postBuffer 524288000 执行完上面的语句后输入:git config…...

Midjourney API 国内申请及对接方式
在人工智能绘图领域,想必大家听说过 Midjourney 的大名吧! Midjourney 以其出色的绘图能力在业界独树一帜。无需过多复杂的操作,只要简单输入绘图指令,这个神奇的工具就能在瞬间为我们呈现出对应的图像。无论是任何物体还是任何风…...
第一章 文件的输入和输出
一 创建一个文件,并写入数据 #include <stdio.h> int main(void) {FILE *fp;fp= fopen("test.txt","w+");fprintf...

网络编程(Modbus进阶)
思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...
k8s从入门到放弃之Ingress七层负载
k8s从入门到放弃之Ingress七层负载 在Kubernetes(简称K8s)中,Ingress是一个API对象,它允许你定义如何从集群外部访问集群内部的服务。Ingress可以提供负载均衡、SSL终结和基于名称的虚拟主机等功能。通过Ingress,你可…...
反射获取方法和属性
Java反射获取方法 在Java中,反射(Reflection)是一种强大的机制,允许程序在运行时访问和操作类的内部属性和方法。通过反射,可以动态地创建对象、调用方法、改变属性值,这在很多Java框架中如Spring和Hiberna…...

【配置 YOLOX 用于按目录分类的图片数据集】
现在的图标点选越来越多,如何一步解决,采用 YOLOX 目标检测模式则可以轻松解决 要在 YOLOX 中使用按目录分类的图片数据集(每个目录代表一个类别,目录下是该类别的所有图片),你需要进行以下配置步骤&#x…...
GitHub 趋势日报 (2025年06月08日)
📊 由 TrendForge 系统生成 | 🌐 https://trendforge.devlive.org/ 🌐 本日报中的项目描述已自动翻译为中文 📈 今日获星趋势图 今日获星趋势图 884 cognee 566 dify 414 HumanSystemOptimization 414 omni-tools 321 note-gen …...
Android第十三次面试总结(四大 组件基础)
Activity生命周期和四大启动模式详解 一、Activity 生命周期 Activity 的生命周期由一系列回调方法组成,用于管理其创建、可见性、焦点和销毁过程。以下是核心方法及其调用时机: onCreate() 调用时机:Activity 首次创建时调用。…...

七、数据库的完整性
七、数据库的完整性 主要内容 7.1 数据库的完整性概述 7.2 实体完整性 7.3 参照完整性 7.4 用户定义的完整性 7.5 触发器 7.6 SQL Server中数据库完整性的实现 7.7 小结 7.1 数据库的完整性概述 数据库完整性的含义 正确性 指数据的合法性 有效性 指数据是否属于所定…...
【无标题】路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论
路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论 一、传统路径模型的根本缺陷 在经典正方形路径问题中(图1): mermaid graph LR A((A)) --- B((B)) B --- C((C)) C --- D((D)) D --- A A -.- C[无直接路径] B -…...
【Elasticsearch】Elasticsearch 在大数据生态圈的地位 实践经验
Elasticsearch 在大数据生态圈的地位 & 实践经验 1.Elasticsearch 的优势1.1 Elasticsearch 解决的核心问题1.1.1 传统方案的短板1.1.2 Elasticsearch 的解决方案 1.2 与大数据组件的对比优势1.3 关键优势技术支撑1.4 Elasticsearch 的竞品1.4.1 全文搜索领域1.4.2 日志分析…...
基于鸿蒙(HarmonyOS5)的打车小程序
1. 开发环境准备 安装DevEco Studio (鸿蒙官方IDE)配置HarmonyOS SDK申请开发者账号和必要的API密钥 2. 项目结构设计 ├── entry │ ├── src │ │ ├── main │ │ │ ├── ets │ │ │ │ ├── pages │ │ │ │ │ ├── H…...