当前位置: 首页 > news >正文

Java虚拟机(JVM)

目录

  • 内存区域划分
    • 堆(Heap)
    • 方法区(Method Area)
    • 程序计数器(Program Counter Register)
    • 虚拟机栈(VM Stack)
    • 本地方法栈(Native Method Stack)
  • 类加载的过程
    • 类加载过程
    • 类加载器
    • 双亲委派模型
  • 垃圾回收机制
    • 1. 找出垃圾
    • 2. 释放垃圾的内存空间

JVM(Java虚拟机)是Java Virtual Machine的缩写,是一种可以执行Java字节码的虚拟机。它为Java应用程序提供了一个与平台无关的执行环境,使得Java程序只需编写一次,就可以在安装了JVM的任何系统上运行
本文主要介绍三个部分:JVM内存区域划分、类加载的过程、垃圾回收机制

内存区域划分

运行时数据区划分如下
在这里插入图片描述

堆(Heap)

堆是JVM中最大的一块内存区域,主要用于存储对象实例,new出来的对象变量都是存储在栈上。堆是所有线程共享的内存区域(只有一份),并且是垃圾回收器的主要工作区域。堆内存大概分为以下几个部分:

  • 新生代(Young Generation):大多数对象的生命周期都很短,因此年轻代被划分为三个部分:Eden区、Survivor0区(S0)、Survivor1区(S1)。对象通常在Eden区被创建,经过一次垃圾回收后,存活的对象会被移动到S0或S1区,每经过一次垃圾回收,存活的对象就会在S0和S1之间移动,直到晋升到老年代。
  • 老年代(Old Generation):在年轻代中经历了多次垃圾回收仍然存活的对象,以及一些大对象(如大数组),会被移动到老年代。老年代的垃圾回收频率较低,因为这里存放的都是生命周期较长的对象。
    在这里插入图片描述

方法区(Method Area)

方法区是所有线程共享的内存区域(只有一份),用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。

程序计数器(Program Counter Register)

程序计数器是一块小的内存空间,它为每个线程私有。程序计数器保存了当前执行的字节码指令的地址(类似于咱们写代码时的行号)。在JVM中,字节码解释器通过改变程序计数器的值来控制执行流程。

程序计数器是程序控制流的指示器,分支、循环、跳转、异常处理、线程恢复等基础功能都需要依靠这个计数器完成。

在这里插入图片描述

虚拟机栈(VM Stack)

虚拟机栈也是线程私有的内存区域,它的生命周期与线程相同。虚拟机栈用于存储局部变量表、操作栈、动态链接、方法出口等信息。每个方法在执行时都会创建一个栈帧(Stack Frame),用于存储局部变量和操作数栈,当方法执行结束时,栈帧会被销毁。

  • 局部变量表(Local Variables):存储方法中的局部变量。

  • 操作数栈(Operand Stack):用于存储计算过程中的中间数据。

  • 动态链接(Dynamic Linking):将符号引用转换为直接引用。

  • 方法出口(Method Exit):用于方法正常退出或异常退出时的清理工作。

本地方法栈(Native Method Stack)

本地方法栈与虚拟机栈类似,Java虚拟机栈是给JVM使用的,而本地方法栈是给本地方法使用的。

提问:下面变量(a、b、c、d、e、f)属于哪个内存区域?

class Test {private int a;private Test b = new Test();private static int c;private static Test d = new Test();public static void main(String[] args) {int e = 1;Test f = new Test();}
}

答:a、b属于堆,c、d属于方法区,e、f属于栈

变量属于哪个区和变量是否为内置类型无关

局部变量==>栈

成员变量==>堆

静态成员变量==>方法区

类加载的过程

JVM类加载是Java程序运行的基础,它涉及将类的.class文件从磁盘加载到内存中,并进行校验、链接和初始化等一系列步骤。

类加载过程

  1. 加载(Loading)

    • 类加载过程的第一步,JVM通过类的全限定名获取其定义这个类的二进制字节流(例如,从.class文件、JAR文件或者网络中获取)。

    • 将这个字节流所代表的静态存储结构转化为JVM内部运行时的数据结构。

    • 在内存中创建一个代表该类的java.lang.Class对象,这个对象将作为程序访问这个类的接口。

      简单来说就是:根据类名找到对应的.class文件,打开文件并读取内容。

  2. 验证(Verification)
    确保读取到的.class文件符合JVM规范,没有安全问题。包括文件格式验证、元数据验证、字节码验证和符号引用验证,确保类的信息是合法的,不会危害虚拟机的安全。

  3. 准备(Preparation)
    为类对象分配内存空间,根据读取到的.class文件内容,确定类对象所需要的空间大小,申请出对应大小的空间,并设置默认初始值(通常是0)。

  4. 解析(Resolution)
    将类、接口、字段和方法的符号引用转换为直接引用。符号引用就是类、字段、方法的全限定名,直接引用保存的是内存中的地址。

  5. 初始化(Initialization)
    执行类的静态初始化和静态变量的赋值操作,执行类中的静态代码块。

类加载器

JVM内置了几种主要的类加载器:

  1. 启动类加载器(Bootstrap ClassLoader)

    负责加载标准库中的类。

  2. 扩展类加载器(Extension ClassLoader)

    负责加载扩展类。

  3. 应用程序类加载器(Application ClassLoader)

    负责加载第三方库中的类、自己写的代码中的类。

双亲委派模型

双亲委派模型(Parent Delegation Model)是Java虚拟机(JVM)中的一种类加载机制。它的核心思想是,当一个类加载器收到类加载请求时,会先委托其父类加载器去完成这个请求,只有在父类加载器无法完成时,自己才会尝试去加载这个类。
在这里插入图片描述

双亲委派模型是类加载5个步骤中第一个步骤中的环节,

工作流程:通过得到的全限定名,

  1. 从Application ClassLoader开始进行加载,此时不会立刻扫描目录,而是把任务委派给Extension ClassLoader
  2. Extension ClassLoader拿到任务后,也不会立刻扫描目录,而是把任务委派给Bootstrap ClassLoader
  3. Bootstrap ClassLoader在目录中进行扫描加载对应的类,如果Bootstrap ClassLoader没找到对应的类,就把任务返回给Extension ClassLoader,如果找到了直接进行后续的类加载过程。类似的,如果Extension ClassLoader没找到,会继续吧任务返回给Application ClassLoader,如果Application ClassLoader找到了直接返回,如果Application ClassLoader没找到,就会抛出异常

类加载请求首先由父类加载器尝试完成,只有在父类加载器无法完成类加载时,才由子类加载器尝试自己去加载。

双亲委派模型机制就是为了防止用户自己定义的类和标准库的类名一样,把标准库的类覆盖掉。

垃圾回收机制

JVM的垃圾回收机制(Garbage Collection, GC)是Java内存管理的重要组成部分,主要目标是自动回收不再使用的对象,释放内存资源,避免内存泄漏和溢出。垃圾回收机制主要工作区域是堆。

GC是如何回收的?

1. 找出垃圾

方案1:给每个对象分配一个计数器,计数器记录的是当前有多少个变量引用了这个对象,每增加一个引用计数器就+1,每减少一个引用就-1。如果计数器为0,表示当前对象没有人引用它,说明这个对象就是垃圾。这个方案存在问题循环引用问题,并且会消耗额外的内存空间,JVM没有采用。
循环引用问题:

class Test {Test t = null;
}
//..........class Main {public static void main(String[] args) {Test a = new Test();Test b = new Test();a.t = b;b.t = a;a = null;b = null;}
}
//这两个对象引用计数器为0不能被释放,但是这两个对象又无法使用

方案2:可达性分析(JVM采用的方案)

JVM会从一组根对象(GCroot)开始,遍历所有可达对象(类似于二叉树、多叉树遍历)。如果某个对象不可通过根对象引用到达,JVM便会将其视为垃圾并回收。常见的GCroot:栈上的局部变量、方法区中的静态成员、常量池中引用指向的对象。

2. 释放垃圾的内存空间

有以下垃圾回收算法

标记-清除算法
先标记出所有存活的对象,然后清除未被标记的对象。这种方法简单,但会产生大量内存碎片(不是连续的空间),后续申请内存的时候可能申请不了(申请的空间一定是连续的)。

复制算法
将可用内存分为大小相等的两块,每次只使用一块,当一块用完,将存活的对象复制到另一块,然后清理已使用过的内存。这种方法解决了内存碎片问题,但代价是内存使用效率降低,复制成本比较大。

标记-整理算法
类似于顺序表删除中间元素的操作。先标记出存活的对象,然后让所有存活的对象向一端移动,之后清理端边界以外的内存区域。这种方法解决了内存碎片问题。这种方法的代价是移动存活对象的开销比较大

分代收集算法(JVM采取的方案)
根据对象存活周期的不同,将堆分为新生代和老年代。

在这里插入图片描述

  • 新生代(Young Generation):大多数对象的生命周期都很短,因此年轻代被划分为三个部分:Eden区、Survivor0区(S0)、Survivor1区(S1)。对象通常在Eden区被创建,经过一次垃圾回收后,存活的对象会被移动到S0或S1区,每经过一次垃圾回收,存活的对象就会在S0和S1之间移动,直到晋升到老年代。
  • 老年代(Old Generation):在年轻代中经历了多次垃圾回收仍然存活的对象,以及一些大对象(如大数组),会被移动到老年代。老年代的垃圾回收频率较低,因为这里存放的都是生命周期较长的对象。

新生代中的对象生命周期短,适合使用复制算法;老年代中的对象生命周期长,适合使用标记-整理算法。

垃圾回收器

现在常见的垃圾回收器有CMS、G1

CMS(Concurrent Mark-Sweep)垃圾回收器

减少STW(Stop The World),标记清除算法,并行处理大部分垃圾回收过程。可能产生内存碎片,老年代需要更大内存。

G1(Garbage First)垃圾回收器

面向服务端的低延迟垃圾回收器,将堆划分为多个区域,优先回收垃圾最多的区域。并行和并发执行,适合大内存应用。

相关文章:

Java虚拟机(JVM)

目录 内存区域划分堆(Heap)方法区(Method Area)程序计数器(Program Counter Register)虚拟机栈(VM Stack)本地方法栈(Native Method Stack) 类加载的过程类加…...

MQ 架构设计原理与消息中间件详解(三)

RabbitMQ实战解决方案 RabbitMQ死信队列 死信队列产生的背景 RabbitMQ死信队列俗称,备胎队列;消息中间件因为某种原因拒收该消息后,可以转移到死信队列中存放,死信队列也可以有交换机和路由key等。 产生死信队列的原因 消息投…...

大数据新视界 --大数据大厂之 Alluxio 数据缓存系统在大数据中的应用与配置

💖💖💖亲爱的朋友们,热烈欢迎你们来到 青云交的博客!能与你们在此邂逅,我满心欢喜,深感无比荣幸。在这个瞬息万变的时代,我们每个人都在苦苦追寻一处能让心灵安然栖息的港湾。而 我的…...

PHP基本语法总结

目录 输出语句 注释 数据类型(变量) 局部和全局作用域 类型比较(松散比较与严格比较) 常量 运算符 并置运算符 不等于 逻辑运算符 条件语句 数组 关联数组 数组排序 一般数组 关联数组 循环 函数 变量函数 魔…...

尚硅谷rabbitmq 2024第30-33节 死信队列 答疑

Virtual host: Type: Name: Durabiity: Arguments: Default for virtual host w ququt.normal.video Durable x-dead-letter-exchange x-dead-1etter-routing-xey x-mAx-1ength X-m在88点0也-6E1 exchange.dead.letter.vide zouting.key.dead.ietter.v 10 String String Number…...

解锁空间距离计算的多种方式-含前端、空间数据库、后端

目录 前言 一、空间数据库求解 1、PostGIS实现 二、GIS前端组件求解 1、Leaflet.js距离测算 2、Turf.js前端计算 三、后台距离计算生成 1、欧式距离 2、Haversice球面距离 3、GeoTools距离计算 4、Gdal距离生成 5、geodesy距离计算 四、成果与生成对比 1、Java不…...

Windows 开发工具使用技巧 QT使用安装和使用技巧 QT快捷键

一、QT配置 1. 安装 Qt 开发框架 1、下载 1、进入下载地址 下载地址1 (官方, 需注册账号): https://www.qt.io/download下载地址2(推荐): http://download.qt.io/http://download.qt.io/archive/qt/ (或更直接的…...

【实战教程】SpringBoot全面指南:快速上手到项目实战(SpringBoot)

文章目录 【实战教程】SpringBoot全面指南:快速上手到项目实战(SpringBoot)1. SpringBoot介绍1.1 SpringBoot简介1.2系统要求1.3 SpringBoot和SpringMVC区别1.4 SpringBoot和SpringCloud区别 2.快速入门3. Web开发3.1 静态资源访问3.2 渲染Web页面3.3 YML与Properti…...

LeetCode讲解篇之1043. 分隔数组以得到最大和

文章目录 题目描述题解思路题解代码题目链接 题目描述 题解思路 对于这题我们这么考虑,我们选择以数字的第i个元素做为分隔子数组的右边界,我们需要计算当前分隔子数组的长度为多少时能让数组[0, i]进行分隔数组的和最大 我们用数组f表示[0, i)区间内的…...

Python知识点:结合Python工具,如何使用TfidfVectorizer进行文本特征提取

开篇,先说一个好消息,截止到2025年1月1日前,翻到文末找到我,赠送定制版的开题报告和任务书,先到先得!过期不候! 如何使用Python的TfidfVectorizer进行文本特征提取 在自然语言处理(…...

Diffusion models(扩散模型) 是怎么工作的

前言 给一个提示词, Midjourney, Stable Diffusion 和 DALL-E 可以生成很好看的图片,那么它们是怎么工作的呢?它们都用了 Diffusion models(扩散模型) 这项技术。 Diffusion models 正在成为生命科学等领域的一项尖端技术&…...

查找回收站里隐藏的文件

在Windows里,每个磁盘分区都有一个隐藏的回收站Recycle, 回收站里保存着用户删除的文件、图片、视频等数据,比如,C盘的回收站为C:\RECYCLE.BIN\,D盘的的回收站为D:\RECYCLE.BIN\,E盘的的回收站为E:\RECYCLE…...

[运维]2.elasticsearch-svc连接问题

Serverless 与容器决战在即?有了弹性伸缩就不一样了 - 阿里云云原生 - 博客园 当我部署好elasticsearch的服务后,由于个人习惯,一般服务会在name里带上svc,所以我elasticsearch服务的名字是elasticsearch-svc: [root…...

Ajax面试题:(第一天)

目录 1.说一下网络模型 2.在浏览器地址栏键入URL,按下回车之后会经历以下流程: 3.什么是三次握手和四次挥手? 4.http协议和https协议的区别 1.说一下网络模型 注:各层含义按自己理解即可 2.在浏览器地址栏键入URL,…...

数据仓库拉链表

数仓拉链表是数据仓库中常用的一种数据结构,用于记录维度表中某个属性的历史变化情况。在实际应用中,数仓拉链表可以帮助企业更好地进行数据分析和决策。 数仓拉链表(Slowly Changing Dimension, SCD)是一种用于处理维表中数据变化…...

【JVM】实战篇

1、内存调优 1.1 内存溢出和内存泄漏 内存泄漏(memory leak):在Java中如果不再使用一个对象,但是该对象依然在GC ROOT的引用链上,这个对象就不会被垃圾回收器回收,这种情况就称之为内存泄漏。 内存泄漏绝…...

2024年9月30日--10月6日(ue5肉鸽结束)

按照月计划,本周把ue肉鸽游戏完成,然后进行ue5太阳系 , 剩余14节,218分钟,如果按照10分钟的视频教程1小时进行完的话,则需要22小时,分布在10月2日-10月6日之间,每天44分钟的视频教程…...

【Python游戏开发】贪吃蛇游戏demo

准备步骤 项目开发使用【Mu 编辑器】 1.新建项目,并导入游戏图片 游戏编写 1.创建场景 SIZE 15 # 每个格子的大小 WIDTH SIZE * 30 # 游戏场景总宽度 HEIGHT SIZE * 30 # 游戏场景总高度def draw():screen…...

pytorch张量基础

引言张量的基础知识 张量的概念张量的属性张量的创建张量的操作 基本运算索引和切片形状变换自动微分 基本概念停止梯度传播张量的设备管理 检查和移动张量CUDA 张量高级操作 张量的视图广播机制分块和拼接张量的复制内存优化和管理 稀疏张量内存释放应用实例 线性回归神经网络…...

深入解析LlamaIndex Workflows【下篇】:实现ReAct模式AI智能体的新方法

之前我们介绍了来自LLM开发框架LlamaIndex的新特性:Workflows,一种事件驱动、用于构建复杂AI工作流应用的新方法(参考:[深入解析LlamaIndex Workflows:构建复杂RAG与智能体工作流的新利器【上篇】]。在本篇中&#xff…...

大话软工笔记—需求分析概述

需求分析,就是要对需求调研收集到的资料信息逐个地进行拆分、研究,从大量的不确定“需求”中确定出哪些需求最终要转换为确定的“功能需求”。 需求分析的作用非常重要,后续设计的依据主要来自于需求分析的成果,包括: 项目的目的…...

黑马Mybatis

Mybatis 表现层&#xff1a;页面展示 业务层&#xff1a;逻辑处理 持久层&#xff1a;持久数据化保存 在这里插入图片描述 Mybatis快速入门 ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/6501c2109c4442118ceb6014725e48e4.png //logback.xml <?xml ver…...

Cesium1.95中高性能加载1500个点

一、基本方式&#xff1a; 图标使用.png比.svg性能要好 <template><div id"cesiumContainer"></div><div class"toolbar"><button id"resetButton">重新生成点</button><span id"countDisplay&qu…...

【CSS position 属性】static、relative、fixed、absolute 、sticky详细介绍,多层嵌套定位示例

文章目录 ★ position 的五种类型及基本用法 ★ 一、position 属性概述 二、position 的五种类型详解(初学者版) 1. static(默认值) 2. relative(相对定位) 3. absolute(绝对定位) 4. fixed(固定定位) 5. sticky(粘性定位) 三、定位元素的层级关系(z-i…...

【SQL学习笔记1】增删改查+多表连接全解析(内附SQL免费在线练习工具)

可以使用Sqliteviz这个网站免费编写sql语句&#xff0c;它能够让用户直接在浏览器内练习SQL的语法&#xff0c;不需要安装任何软件。 链接如下&#xff1a; sqliteviz 注意&#xff1a; 在转写SQL语法时&#xff0c;关键字之间有一个特定的顺序&#xff0c;这个顺序会影响到…...

2025盘古石杯决赛【手机取证】

前言 第三届盘古石杯国际电子数据取证大赛决赛 最后一题没有解出来&#xff0c;实在找不到&#xff0c;希望有大佬教一下我。 还有就会议时间&#xff0c;我感觉不是图片时间&#xff0c;因为在电脑看到是其他时间用老会议系统开的会。 手机取证 1、分析鸿蒙手机检材&#x…...

相机Camera日志分析之三十一:高通Camx HAL十种流程基础分析关键字汇总(后续持续更新中)

【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了:有对最普通的场景进行各个日志注释讲解,但相机场景太多,日志差异也巨大。后面将展示各种场景下的日志。 通过notepad++打开场景下的日志,通过下列分类关键字搜索,即可清晰的分析不同场景的相机运行流程差异…...

uniapp中使用aixos 报错

问题&#xff1a; 在uniapp中使用aixos&#xff0c;运行后报如下错误&#xff1a; AxiosError: There is no suitable adapter to dispatch the request since : - adapter xhr is not supported by the environment - adapter http is not available in the build 解决方案&…...

企业如何增强终端安全?

在数字化转型加速的今天&#xff0c;企业的业务运行越来越依赖于终端设备。从员工的笔记本电脑、智能手机&#xff0c;到工厂里的物联网设备、智能传感器&#xff0c;这些终端构成了企业与外部世界连接的 “神经末梢”。然而&#xff0c;随着远程办公的常态化和设备接入的爆炸式…...

return this;返回的是谁

一个审批系统的示例来演示责任链模式的实现。假设公司需要处理不同金额的采购申请&#xff0c;不同级别的经理有不同的审批权限&#xff1a; // 抽象处理者&#xff1a;审批者 abstract class Approver {protected Approver successor; // 下一个处理者// 设置下一个处理者pub…...