JVM相关
1.JVM内存区域
一个运行起来的java进程就是一个Java虚拟机,就需要从操作系统中申请一大块内存。
内存中会根据作用的不同被划分成不同的区域:
(1)栈:存储的内容是代码在执行过程中,方法之间的调用关系(栈中每一个元素就是一个栈帧,代表一个方法的调用,包含方法的形参,返回值,局部变量)。
(2)堆:这里存储的内容是代码中new的对象
(3)方法区(1.8开始:元数据区):存储类对象(.class文件加载到内存就成为了类对象)
(4)程序计数器:存放每个线程,下一条指令执行的地址。空间较小主要就是用来存放一个“地址”,表示下一条要执行的指令,在内存的哪个地方(在方法区中去找下一条指令,指令是以二进制的形式存储在类对象中)。
程序计数器中的值会随着指令的执行,从而自动进行更新,去指向下一条指令。
如果是顺序执行的代码,那么下一条执行的指令地址就是把指令地址进行递增。
如果是条件循环执行的代码,那么下一条执行的指令地址就可能会跳到比较远的地址。
ps:栈和程序计数器每一个java线程一份,而堆和方法区是每一个java进程一份。(仅限java,放在c++中就不一定是这样了)
2.JVM类加载
(1)基本流程:
java代码经过编译后生成.class文件,java程序要想运行起来就需要将jvm读取这个.class文件,并且把里面的内容构造成类对象,保存到内存的方法区中。
官方文档中把类加载的过程分成了5个步骤:
1)加载:找到.class文件,并且打开文件,读取文件中的内容(通过全限定名称查找)
2)验证:检查当前二进制文件是否符合格式的要求,具体格式
3)准备:给类对象分配内存空间,并且为不被final修饰的static变量赋初始默认值(被final修饰的变量在此时会被赋值成程序员给定的值)
4)解析:针对类对象中字符串常量的处理,进行了一些初始化的操作。(符号引用到直接引用)
字符串常量在经过编译之后,eg:final String s = "hello",s本来是存储内存地址,但在.class文件中会重新针对该字符串进行创建出一个引用,此时这个引用就不是存储内存地址了,而是存储文件偏移量(字符串长度),通过这个变量就可以知道目前字符串处于哪个位置。到解析的阶段(类加载的时候),会重新将这个引用替换成内存地址。
5)初始化:对类对象中的各种属性进行初始化,还需执行静态代码块和加载一下父类(子类中调用构造方法,会先帮助父类进行构造)
(2)双亲委派模型:
是在加载过程中的第一个步骤。
首先需要了解一下类加载器:
是JVM中的一个模块,JVM内置了三个类加载器:
1)BootStrap ClassLoader
2)Extension ClassLoader
3)Application ClassLoader
这三个类加载器之间的关系就好似爷父子之间的关系,但不是靠继承构成的,而是由类加载中的一个属性(parent)来指向父类加载器。
加载的具体流程是:
①根据给定的全限定类名,找到对应的.class文件。
②从Application ClassLoader作为入口,开始执行查找的逻辑。
③Application ClassLoader不会立即扫描自己所负责的目录(负责搜索项目当前目录和第三方库的对应目录),而是会交给自己的父类加载器Extension ClassLoader。
④Extension ClassLoader不会立即扫描自己所负责的目录(负责搜索JDK中一些扩展库对应的目录,是JDK标准库之外的一些库,属于对JDK标准库的扩展),而是会交给自己的父类加载器BootStrap ClassLoader。
⑤BootStrap ClassLoader,也不会立即扫描自己所负责的目录(负责搜索JDK标准库对应目录),而是会交给自己的父类加载器,但是却发现没有父类加载器,因此只能区扫描自己负责的目录,一旦在标准库中查找到对应类的.class文件,此时加载的过程就完了,扫描结束过后如果没有扫描到,就会交给它的子类加载器(Extension ClassLoader)扫描。
⑥如果在Extension ClassLoader扫描到了就结束加载过程,没有扫描到就交给它的子类加载器(Application ClassLoader)扫描。
⑦如果在Application ClassLoader扫描到了就结束加载过程,没有扫描到此时应该交给它的子类加载器扫描,但是发现没有了,所以此时会抛出一个异常ClassNotFoundException
总结:所谓的双亲委派模型其实就是一个按照优先级查找.class文件的一个过程,之所以有这么一套流程,是为了确保JDK标准库扫描的优先级最高,其次是扩展库,最后才是项目当前目录和引入的第三方库对应目录。就好比:你在自己的代码中使用String(导入的包是java.lang.String),在类加载的时候加载的JDK标准库中的类,而不是自己写的这个类。
3.JVM垃圾回收机制(GC垃圾回收)
在java中new对象,是动态申请内存(运行时分配),如果一个资源申请了内存空间,长时间不使用但是不释放,就可能会造成内存泄漏。
在java中给出了一个方案,也就是垃圾回收机制,让JVM,自动判定某个内存是否不再使用了,
如果后面这个内存确实不用了,JVM就会自动回收把这个内存给回收掉了,此时就不需要手动回收了。
GC是垃圾回收,GC回收的目标是内存中的对象。对于java来说就是释放堆上的new出的对象,栈上的对象是随着栈帧的生命周期(方法执行结束,栈帧自然销毁,内存自然释放),静态变量,生命周期是整个程序,这个始终存在就意味着静态变量无需释放的,真正释放的就是堆上的对象。
GC回收垃圾的过程主要有两个步骤:
(1)找到垃圾
有两种主流的方案:
①引用计数
new出来的对象,会单独划分空间,来保存有一个计数器,计的是当前有多少引用指向该对象。
如果一个对象没有引用指向了(即引用计数为0),就可以将该对象视为垃圾了。
但是使用该种方式可能会存在两种问题:
·比较浪费内存:
计数器怎么说也得有两个字节,如果对象本身比较小,那么此时这个计数器所占空间比例就比较大了。
·存在循环引用问题:

②可达性分析:
有一组线程,周期性扫描代码中的所有对象,把所有可以访问到的对象,都给标记成“可达”,反之,如果经过扫描后,不可达的对象,就成垃圾了,需要被回收。
eg:

当然这里的遍历不一定是二叉搜索树,这里可达的实现大概率是靠N叉搜索树实现,这一步就是针对当前对象,看对象中有多少不同引用类型的成员,然后再对每一个类型的成员进行进一步的遍历。
通过上述过程,不难看出可达性分析是比较耗费资源的(开销较大)。
(2)回收垃圾
有三种基本的回收思路:
①标记删除:
扫描到一个不可达的对象,就直接进行释放,这个方案非常不好,那就是会产生很多的内存碎片。释放代码,是为了让其他代码能够申请一块连续的内存空间,随着时间的推移,内存碎片的情况就会愈演愈烈,就会导致后续申请连续内存空间变得困难。
②复制算法:
通过复制的方式,把有效的对象,归类到一起,在同一释放剩下的对象。
也就是把内存一分为二,一次只用其中一半。但这种方式有两个明显的问题:
a.内存利用率不高
b.如果有效的对象很多,那么复制的开销将会很大
③标记整理:
既能解决内存碎片的问题,又能够解决上述内存利用率不高的问题。
eg:

类似于顺序表删除元素的搬运操作,使用该种方式搬运开销仍然很大。
而JVM中GC垃圾回收主要思想是分代回收(具体实现可能有一些调整和优化),是对上述思路的集合,让不同的方案,扬长避短。
分代回收有一个很重要机制就是:对象能活过的GC扫描轮次越多,就是越老(代表当前对象是暂时不会被释放的)
eg:下图是整个分代回收的全部过程:

相关文章:
JVM相关
1.JVM内存区域 一个运行起来的java进程就是一个Java虚拟机,就需要从操作系统中申请一大块内存。 内存中会根据作用的不同被划分成不同的区域: (1)栈:存储的内容是代码在执行过程中,方法之间的调用关系&a…...
9.18 微信小程序开发笔记
如何获取英语单词的发音,使其能在小程序界面通过点击外发? 1.通过外界API获取(例如有道API) 不下载音频文件,每次需要时直接API获取发音,存储压力小。但是一般的API都有使用次数限制,在背单词…...
dpdk课程学习之练习笔记八(dpvs的了解)
只是看到这个,跟着流程做一下练习,了解这个东东是干啥的,再就是搭建环境,基于dpdk的环境,顺手也就练习dpdk的环境搭建了。 0:总结 1:知道了lvs能实现的功能,挺强大。 2࿱…...
Linux标准IO-系统调用详解
1.1 系统调用 系统调用(system call)其实是 Linux 内核提供给应用层的应用编程接口(API),是 Linux 应用层进入内核的入口。不止 Linux 系统,所有的操作系统都会向应用层提供系统调用,应用程序通…...
LeetCode004-两个有序数组的中位数-最优算法代码讲解
最有帮助的视频讲解 【LeetCode004-两个有序数组的中位数-最优算法代码讲解】 https://www.bilibili.com/video/BV1H5411c7oC/?share_sourcecopy_web&vd_sourceafbacdc02063c57e7a2ef256a4db9d2a 时间复杂度 O ( l o g ( m i n ( m , n ) ) ) O(log(min(m,n))) O(log(min(…...
Unity携程Coroutine用法
一.携程概述 官方的解释是,携程允许你可以在多个帧中执行任务。在Unity中,携程是一个可以暂停并在后续帧中从暂停处继续执行的方法。 二.携程写法 下面示例使用携程和Update打印前5帧的时间间隔,展示了携程的基础写法 using System.Colle…...
腾讯百度阿里华为常见算法面试题TOP100(5):子串、堆
之前总结过字节跳动TOP50算法面试题: 字节跳动常见算法面试题top50整理_沉迷单车的追风少年-CSDN博客_字节算法面试题 子串 560.和为K的子数组...
「数据科学」清洗数据,真实数据集中缺失值的查看与处理
在数据科学的工作过程中,我们通过查看数据的基本要素和元数据之后,需要根据查看的结果,考虑是否需要清洗数据。缺失值的查看与处理,就是清洗数据的一部分。如果我们的数据集中,存在缺失值的话,就需要考虑如…...
彩蛋岛 销冠大模型案例
彩蛋岛 销冠大模型案例 任务: https://kkgithub.com/InternLM/Tutorial/tree/camp3/docs/EasterEgg/StreamerSales 视频 https://www.bilibili.com/video/BV1f1421b7Du/?vd_source4ffecd6d839338c9390829e56a43ca8d 项目git地址: https://kkgithu…...
大数据Flink(一百二十一):Flink CDC基本介绍
文章目录 Flink CDC基本介绍 一、什么是CDC 二、CDC的实现机制 三、传统 CDC ETL 分析 四、基于 Flink CDC 的 ETL 分析 五、什么是 Flink CDC 六、…...
SqlServer自定义类型的使用
目录 前言分类基于标量类型新建查询语句 用户定义的表类型新建查询语句 基于 CLR新建查询语句 前言 最近接触了SqlServer的自定义类型–TYPE,在此记录一下所得 分类 在 SQL Server 中,用户定义的类型(User-Defined Types, UDT)…...
LeetCode 滑动窗口 滑动子数组的美丽值
滑动子数组的美丽值 给你一个长度为 n 的整数数组 nums ,请你求出每个长度为 k 的子数组的 美丽值 。 一个子数组的 美丽值 定义为:如果子数组中第 x 小整数 是 负数 ,那么美丽值为第 x 小的数,否则美丽值为 0 。 请你返回一个包含…...
【JavaEE初阶】多线程(4)
欢迎关注个人主页:逸狼 创造不易,可以点点赞吗~ 如有错误,欢迎指出~ 目录 线程安全的 第四个原因 代码举例: 分析原因 解决方法 方法1 方法2 wait(等待)和notify(通知) wait和sleep区别 线程安全的 第四个原因 内存可见性,引起的线程安全问…...
初识 C++ ( 1 )
引言:大家都说c是c的升级语言。我不懂这句话的含义后来看过解释才懂。 一、面向过程语言和面向对象语言 我们都知道C语言是面向过程语言,而C是面向对象语言,说C和C的区别,也就是在比较面向过程和面向对象的区别。 1.面向过程和面向…...
Python数据分析 Pandas库-初步认识
Python数据分析 Pandas库-初步认识 认识Pandas pandas是一个非常实用的Python工具,我们可以把它想象成一个超级强大的表格处理工具,它比Excel更智能,操作更为简单。pands可以从各种文件格式(CSV、JSON、SQL、Excel࿰…...
Flutter问题记录 - 适配Xcode 16和iOS 18
文章目录 前言开发环境问题及解决方案1. Upload Symbols Failed2. type UIApplication does not conform to protocol Launcher3. method does not override any method from its superclass 最后 前言 为了新的镜像功能升级了macOS 15和iOS 18,Xcode也不可避免的需…...
VMware ESXi 7.0U3q macOS Unlocker 集成驱动版更新 OEM BIOS 2.7 支持 Windows Server 2025
VMware ESXi 7.0U3q macOS Unlocker 集成驱动版更新 OEM BIOS 2.7 支持 Windows Server 2025 VMware ESXi 7.0U3q macOS Unlocker & OEM BIOS 2.7 集成网卡驱动和 NVMe 驱动 (集成驱动版) ESXi 7.0U3 标准版集成 Intel 网卡、Realtek USB 网卡 和 NVMe 驱动 请访问原文链…...
大数相乘,大数相加
大数相乘: #include <iostream> #include <vector> #include <string>std::vector<int> multiply(const std::vector<int>& num1, const std::vector<int>& num2) {int n1 num1.size();int n2 num2.size();std::ve…...
Spring Boot配置文件敏感信息加密
一,背景 Spring Boot应用中的数据库、Redis、Nacos、MQ等的用户名、连接地址、密码在配置文件中一般都是明文存储,如果系统被系统攻破或者配置文件所在的目录读权限被破解,又或者是动态配置文件被窃取,内部人员或者黑客很容易通过…...
Java操作数栈分析
Java 的操作数栈(Operand Stack)是 JVM 的运行时数据区域之一,位于每个线程的栈帧中。操作数栈用于临时存储操作的中间结果和数据(操作数),在方法执行时,JVM 的字节码指令会对操作数栈进行操作。…...
AI-调查研究-01-正念冥想有用吗?对健康的影响及科学指南
点一下关注吧!!!非常感谢!!持续更新!!! 🚀 AI篇持续更新中!(长期更新) 目前2025年06月05日更新到: AI炼丹日志-28 - Aud…...
C# SqlSugar:依赖注入与仓储模式实践
C# SqlSugar:依赖注入与仓储模式实践 在 C# 的应用开发中,数据库操作是必不可少的环节。为了让数据访问层更加简洁、高效且易于维护,许多开发者会选择成熟的 ORM(对象关系映射)框架,SqlSugar 就是其中备受…...
优选算法第十二讲:队列 + 宽搜 优先级队列
优选算法第十二讲:队列 宽搜 && 优先级队列 1.N叉树的层序遍历2.二叉树的锯齿型层序遍历3.二叉树最大宽度4.在每个树行中找最大值5.优先级队列 -- 最后一块石头的重量6.数据流中的第K大元素7.前K个高频单词8.数据流的中位数 1.N叉树的层序遍历 2.二叉树的锯…...
【生成模型】视频生成论文调研
工作清单 上游应用方向:控制、速度、时长、高动态、多主体驱动 类型工作基础模型WAN / WAN-VACE / HunyuanVideo控制条件轨迹控制ATI~镜头控制ReCamMaster~多主体驱动Phantom~音频驱动Let Them Talk: Audio-Driven Multi-Person Conversational Video Generation速…...
智能AI电话机器人系统的识别能力现状与发展水平
一、引言 随着人工智能技术的飞速发展,AI电话机器人系统已经从简单的自动应答工具演变为具备复杂交互能力的智能助手。这类系统结合了语音识别、自然语言处理、情感计算和机器学习等多项前沿技术,在客户服务、营销推广、信息查询等领域发挥着越来越重要…...
动态 Web 开发技术入门篇
一、HTTP 协议核心 1.1 HTTP 基础 协议全称 :HyperText Transfer Protocol(超文本传输协议) 默认端口 :HTTP 使用 80 端口,HTTPS 使用 443 端口。 请求方法 : GET :用于获取资源,…...
【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的“no matching...“系列算法协商失败问题
【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的"no matching..."系列算法协商失败问题 摘要: 近期,在使用较新版本的OpenSSH客户端连接老旧SSH服务器时,会遇到 "no matching key exchange method found", "n…...
热烈祝贺埃文科技正式加入可信数据空间发展联盟
2025年4月29日,在福州举办的第八届数字中国建设峰会“可信数据空间分论坛”上,可信数据空间发展联盟正式宣告成立。国家数据局党组书记、局长刘烈宏出席并致辞,强调该联盟是推进全国一体化数据市场建设的关键抓手。 郑州埃文科技有限公司&am…...
【WebSocket】SpringBoot项目中使用WebSocket
1. 导入坐标 如果springboot父工程没有加入websocket的起步依赖,添加它的坐标的时候需要带上版本号。 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId> </dep…...
相关类相关的可视化图像总结
目录 一、散点图 二、气泡图 三、相关图 四、热力图 五、二维密度图 六、多模态二维密度图 七、雷达图 八、桑基图 九、总结 一、散点图 特点 通过点的位置展示两个连续变量之间的关系,可直观判断线性相关、非线性相关或无相关关系,点的分布密…...
