02|JVM内存模型

news2025/2/24 6:17:03

1. JVM整体结构及内存模型

在这里插入图片描述

1.1 类装载子系统

负责加载字节码文件并将其转换为可以执行的Java类。类加载器子系统包括三个主要的类加载器:Bootstrap ClassLoader(引导类加载器)、Extension ClassLoader(扩展类加载器)和 Application ClassLoader(应用程序类加载器)。它们负责从不同的位置加载类文件, 加载到Runtime data area 中的method area(方法区)

1.2 字节码执行引擎

负责执行Java字节码指令。执行引擎包括解释器和即时编译器。解释器逐条解释字节码指令并执行相应的操作,而即时编译器将字节码编译成本地代码以提高执行效率。

1.3 本地方法接口(Native Interface)

与native libraries(本地方法库)交互,是其他编程语言交互的接口。

1.4 运行时数据区(JVM内存模型)

包括方法区、堆、虚拟机栈、本地方法栈程序计数器。这些区域负责存储运行时数据,包括类的信息、对象实例、方法的局部变量和操作数栈等。

1.4.1 程序计数器

程序计数器(Program Counter Register)是一块较小的内存空间,它可以看作是当前线程所执行的字节码的行号指示器。在Java虚拟机的概念模型里,字节码解释器工作时就是通过改变这个计数器的值来选取下一条需要执行的字节码指令(每执行完一个指令,字节码执行引擎会立刻动态的修改程序技术器中的值(因为是字节码执行引擎执行的,所以字节码执行引擎每执行完一行代码,会去修改程序计数器中的值)),它是程序控制流的指示器,分支、循环、跳转、异常处理、线程恢复等基础功能都需要依赖这个计数器来完成。
由于Java虚拟机的多线程是通过线程轮流切换、分配处理器执行时间的方式来实现的,在任何一个确定的时刻,一个处理器(对于多核处理器来说是一个内核)都只会执行一条线程中的指令。因此,为了线程切换后能恢复到正确的执行位置,每条线程都需要有一个独立的程序计数器,各条线程之间计数器互不影响,独立存储,我们称这类内存区域为“线程私有”的内存
如果线程正在执行的是一个Java方法,这个计数器记录的是正在执行的虚拟机字节码指令的地址;如果正在执行的是本地(Native)方法,这个计数器值则应为空(Undefined)。此内存区域是唯一一个在《Java虚拟机规范》中没有规定任何OutOfMemoryError情况的区域,生命周期随着线程的创建而创建,随着线程的结束而死亡

1.4.2 JAVA虚拟机栈

与程序计数器一样,Java虚拟机栈(Java Virtual Machine Stack)也是线程私有的,它的生命周期与线程相同。栈会给每个线程分配一个私有的栈,其内部保存一个个的栈帧。虚拟机栈描述的是Java方法执行的线程内存模型:每个方法被执行的时候,Java虚拟机都会同步创建一个栈帧(Stack Frame)用于存储局部变量表、操作数栈、动态链接(在程序运行时将符号引用替换为直接引用(常量池中的内存地址),常量池是放在方法区中)、方法出口(存储的是主方法调用子方法的地址)等信息。每一个方法被调用直至执行完毕的过程,就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。
在《Java虚拟机规范》中,对这个内存区域规定了两类异常状况:如果线程请求的栈深度大于虚拟机所允许的深度,将抛出StackOverflowError异常;如果Java虚拟机栈容量可以动态扩展,当栈扩展时无法申请到足够的内存会抛出OutOfMemoryError异常。
特点是FILO(先进后出),拿数据从栈顶拿;局部方法先执行完,执行完后,局部方法的局部变量内存空间全部释放掉(出栈)

1.4.3 堆

Java堆(Java Heap)是虚拟机所管理的内存中最大的一块,所有线程共享,在虚拟机启动时创建;
唯一目的就是存放对象实例,几乎所有的对象实例以及数据都在这里分配内存,new出来的对象存放在堆中;由于即时编译技术的进步,尤其是逃逸分析技术的日渐强大,栈上分配、标量替换优化手段已经导致一些微妙的变化悄然发生,所以说Java对象实例都分配在堆上也渐渐变得不是那么绝对了;
根据《Java虚拟机规范》的规定,Java堆可以处于物理上不连续的内存空间中,但在逻辑上它应该被视为连续的,这点就像我们用磁盘空间去存储文件一样,并不要求每个文件都连续存放。但对于大对象(典型的如数组对象),多数虚拟机实现出于实现简单、存储高效的考虑,很可能会要求连续的内存空间。
Java堆既可以被实现成固定大小的,也可以是可扩展的,不过当前主流的Java虚拟机都是按照可扩展来实现的(通过参数-Xmx和-Xms设定)。如果在Java堆中没有内存完成实例分配,并且堆也无法再扩展时,Java虚拟机将会抛出OutOfMemoryError异常。

堆分为年轻代(Eden, s0 和s1)(1/3)和老年代(2/3),配比是可以调的;
new出来的对象一般是放在堆中的Eden;
静态变量user是放在方法区中,但是它是new出来的对象,new出来的对象是放在堆中的,所以方法区中存储的是堆中user对象的内存地址;

为什么要STW?

因为如果不停止用户线线程,当你还在根据gc root往下找的时候,还没结束,此时如果用户线程结束了,那么整个堆空间都释放掉了,此时整个链路都是垃圾对象,那么这样的话GC并没什么作用,不可能在回去遍历一次,所以JVM直接STW。

1.4.4 方法区

JDK17以前方法区被称为永久代,1,8开始,使用元空间取代了永久代,元空间使用的是本地内存JVM内存之外的部分叫做本地内存);1.8之后元空间存放在堆外内存中;
方法区(Method Area)与Java堆一样,是各个线程共享的内存区域,它用于存储已被虚拟机加载的类型信息、常量、静态变量、即时编译器编译后的代码缓存等数据。
字符串常量池在JDK7的时候放到了堆空间中
方法区中的元空间直接用的是物理内存(内存条),默认初始值是21M,当类信息很大达到21M时,会触发full gc,回收堆和方法区
方法区容量自动扩容机制,假设初始full gc后发现并没有回收多少,下次触发full gc的灵界点的大小>21M,一般元空间设置为256/512M。一定要设置值,否则大量full gc。
与永久代最大的不同就是,如果不指定大小的话,随着更多类的创建,虚拟机会耗尽所有可用的系统内存。

1.4.5 本地方法栈

本地方法栈(Native Method Stacks)与虚拟机栈所发挥的作用是非常相似的,其区别只是虚拟机栈为虚拟机执行Java方法(也就是字节码)服务,而本地方法栈则是为虚拟机使用到的本地(Native)方法服务
《Java虚拟机规范》对本地方法栈中方法使用的语言、使用方式与数据结构并没有任何强制规定, 因此具体的虚拟机可以根据需要自由实现它,甚至有的Java虚拟机(譬如Hot-Spot虚拟机)直接就把本地方法栈和虚拟机栈合二为一。与虚拟机栈一样,本地方法栈也会在栈深度溢出或者栈扩展失败时分别抛出StackOverflowError和OutOfMemoryError异常。

1.4.6 JVM执行引擎

JVM中的元空间确实包含了大量的元数据,这些元数据为运行时提供了关于类、方法和字段的重要信息。但为什么在有了这么丰富的元数据之后,JVM还需要保留字节码呢?
答案就在执行引擎。执行引擎是JVM的核心部分,它负责将字节码翻译为可以在特定硬件上运行的机器代码。但是,这并不是一次性的过程。为了提高性能,JVM会使用Just-In-Time (JIT) 编译技术,将“热点”代码段编译成机器代码,从而大大加速程序的执行速度
因此,尽管元数据为JVM提供了关于类和方法的大量信息,但字节码的存在是为了允许执行引擎进行即时编译优化。这个细节不仅揭示了JVM的优雅设计,也为我们展现了Java为什么能在保持跨平台特性的同时,还能提供出色的性能。

基本结构与组件
执行引擎是JVM中的一个核心组件,负责管理和执行Java字节码。它主要由以下部分组成:
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

输入一个整数n,输出这个整数的二进制的0和1的个数

输入一个整数n&#xff0c;输出这个整数的二进制的0和1的个数:除二取余法 代码&#xff1a; #include <cstdio> int main() {int n;scanf_s("%d", &n);int arr[2] { 0 };while (n) {int yu n % 2;arr[yu];n n / 2;}printf("0的个数是&#xff1a…

2024-02-29 作业

作业要求&#xff1a; 编写链表&#xff0c;链表里面随便搞点数据 使用 fprintf 将链表中所有的数据&#xff0c;保存到文件中 使用 fscanf 读取文件中的数据&#xff0c;写入链表中 运行代码&#xff1a; main.c #include "link.h" int main(int argc, const char…

大数据毕业设计—基于Python旅游数据采集可视化分析推荐系统(完整系统源码+数据库+详细文档+全源码解析)

文章目录 基于Python旅游数据采集可视化分析推荐系统&#xff08;完整系统源码数据库详细文档全源码解析&#xff09;源码获取方式在文章末尾源码获取方式在文章末尾一、项目概述二、项目说明三、开发环境四、功能实现五、系统页面实现用户登录注册系统首页数据操作管理价格与销…

机试指南:Ch5:线性数据结构 Ch6:递归与分治

文章目录 第5章 线性数据结构1.向量 vector2.队列 queue(1)队列的特点、应用(2)基本操作(3)例题例题1&#xff1a;约瑟夫问题2 &#xff08;难度&#xff1a;中等&#xff09; (4)习题习题1&#xff1a;排队打饭 &#xff08;难度&#xff1a;中等&#xff09; 3.栈 stack(1)栈…

jsjiami.v7关于js加密运行环境的探索

浏览器环境、Node.js 环境和 vm2 环境之间存在一些区别&#xff0c;包括全局对象、核心模块和一些环境特定的 API。下面是一些区别的简要概述&#xff0c;以及一些代码示例来突显它们之间的不同。 1. 浏览器环境&#xff1a; 全局对象&#xff1a; 浏览器环境&#xff1a; 全…

加速AI测试领域的进化,顶尖专家与名校教授强强联合,助你快速成为人工智能测试领域的精英

随着人工智能在各行各业的广泛应用&#xff0c;学习并掌握AI技术在软件测试中的应用变得至关重要。不仅能使你跟上行业的发展趋势&#xff0c;还能提升你的竞争力。而且&#xff0c;市场对具备AI测试技能的测试工程师的需求正日益增长&#xff0c;这使得掌握这些技能能够帮助你…

Linux网络编程(四-TCP协议)

目录 一、TCP概念 二、TCP的首部格式 三、TCP可靠传输机制 3.1 确认应答机制 3.2 超时重传机制 3.3 连接管理 3.3.1 三次握手 3.3.2 四次挥手 3.4 流量控制 3.5 拥塞控制 四、TCP效率机制 4.1 滑动窗口 4.2 重发控制 4.3 延迟应答 4.4 捎带应答 五、TCP的…

【Linux C | 网络编程】gethostbyname 函数详解及C语言例子

&#x1f601;博客主页&#x1f601;&#xff1a;&#x1f680;https://blog.csdn.net/wkd_007&#x1f680; &#x1f911;博客内容&#x1f911;&#xff1a;&#x1f36d;嵌入式开发、Linux、C语言、C、数据结构、音视频&#x1f36d; &#x1f923;本文内容&#x1f923;&a…

【Java程序设计】【C00323】基于Springboot的高校科研信息管理系统(有论文)

基于Springboot的高校科研信息管理系统&#xff08;有论文&#xff09; 项目简介项目获取开发环境项目技术运行截图 项目简介 这是一个基于Springboot的高校科研信息管理系统&#xff0c;本系统有管理员、学校管理员、科研人员三种角色&#xff1b; 管理员&#xff1a;首页、个…

企业数字化转型的第一步:由被动多云向主动多云转变

随着经济环境、市场形势、技术发展、用户需求等诸多因素的变化&#xff0c;数字化转型为企业进一步提升效率和竞争力、提供更加丰富的个性化产品和服务、进行业务场景创新、探寻新的增长机会和运营模式提供了崭新的途径。越来越多的企业意识到&#xff0c;数字化转型已不是企业…

数据仓库与数据挖掘概述

目录 一、数据仓库概述 &#xff08;一&#xff09;从传统数据库到数据仓库 &#xff08;二&#xff09;数据仓库的4个特征 &#xff08;三&#xff09;数据仓库系统 &#xff08;四&#xff09;数据仓库系统体系结构 &#xff08;五&#xff09;数据仓库数据的粒度与组织…

机器人内部传感器阅读梳理及心得-速度传感器-数字式速度传感器

在机器人控制系统中&#xff0c;增量式编码器既可以作为位置传感器测量关节相对位置&#xff0c;又可作为速度传感器测量关节速度。当作为速度传感器时&#xff0c;既可以在模拟量方式下使用&#xff0c;又可以在数字量方式下使用。 模拟式方法 在这种方式下&#xff0c;需要…

day02_前后端环境搭建(前端工程搭建,登录功能说明,后端项目搭建)

文章目录 1. 软件开发介绍1.1 软件开发流程1.2 角色分工1.3 软件环境1.4 系统的分类 2. 尚品甄选项目介绍2.1 电商基本概念2.1.1 电商简介2.1.2 电商模式B2BB2CB2B2CC2BC2CO2O 2.2 业务功能介绍2.3 系统架构介绍2.4 前后端分离开发 3. 前端工程搭建3.1 Element-Admin简介3.2 El…

django框架不调试下会被达出史(sql查询次数,消耗时间)

1:使用pycharm编辑器里面 2:安装django-debug-toolbar 3:进行调试查询 https django框架调试,各个面板查询消耗时间&#xff0c;pycharm,debug 1&#xff1a;settings.py INSTALLED_APPS列表中添加 INSTALLED_APPS [# 使用多合一有点慢# multi_captcha_admin,# 多合一验证码i…

Git安装的一些步骤解说(小白好奇心严重版本)

Use bundled OpenSSH 安装 Git 时&#xff0c;您面临的选择是使用 Git 自带的 SSH 客户端&#xff08;bundled OpenSSH&#xff09;还是使用系统上已安装的外部 SSH 客户端&#xff08;external OpenSSH&#xff09;。以下是两个选项的一些考虑因素&#xff1a; 使用 Git 自带的…

2/29作业

typedef int datatype; typedef struct link_list { union { int len; datatype data; }; struct link_list *next; }link_list,*link_p; #include "link_list.h" int main(int argc,const char *argv[]) { //创建链表并填入数据 …

阿里云服务器大降价20%,简单拥有五年三台2h4gECS,组建公网集群

要在阿里云ECS上组建集群&#xff0c;您可以按照以下步骤进行操作&#xff1a; 创建ECS实例&#xff1a;登录阿里云控制台&#xff0c;选择ECS实例&#xff0c;点击“创建实例”按钮。根据实际需求选择实例的配置参数&#xff0c;例如实例规格、操作系统、网络等。根据需要选择…

Spring Boot Profiles简单介绍

Spring Boot application.properties和application.yml文件的配置 阅读本文之前&#xff0c;请先阅读上面的配置文件介绍。 Spring Boot Profiles是一个用于区分不同环境下配置的强大功能。以下是如何在Spring Boot应用程序中使用Profiles的详细步骤和代码示例。 1. 创…

buuctf_web_loveSQL

题目&#xff1a; 上面有行小红字&#xff0c;“用 sqlmap 是没有灵魂的”,呵呵。。嗯&#xff0c;确实 啥也憋说&#xff0c;先上万能钥匙&#xff1a; a or 11 # a’ or 11 # a" or 11 # 尝试后的结果&#xff0c;可以发现该SQL验证是单引号&#xff0c;a or 11 #注入过…

预训练大模型LLM的PEFT之—— Prefix Tuning

简介 Prefix Tuning是2021.01提出来的&#xff0c;在它之前&#xff0c;我们使用prompt主要是人工设计模板或者自动化搜索模板&#xff0c;也就是prompt范式的第一阶段&#xff0c;就是在输入上加上prompt文本&#xff0c;再对输出进行映射。这种离散模板对模型的鲁棒性很差。…