【JVM】Java内存区域图文详解

news2024/9/28 1:16:38

1.JVM运行时区域总览

Java 虚拟机在执行 Java 程序的过程中会把它管理的内存划分成若干个不同的数据区域。

JVM运行时区域也成为Java内存区域。 在讨论Java内存模型时,通常将其分为线程共享区域和线程私有区域:

2.线程私有区域

2.1.程序计数器

程序计数器是一块较小的内存空间,可以看作是当前线程所执行的字节码的行号指示器。字节码解释器工作时通过改变这个计数器的值来选取下一条需要执行的字节码指令,分支、循环、跳转、异常处理、线程恢复等功能都需要依赖这个计数器来完成。

程序计数器主要有两个作用:

  1. 字节码解释器通过改变程序计数器来依次读取指令,从而实现代码的流程控制,如:顺序执行、选择、循环、异常处理。

  2. 在多线程的情况下,程序计数器用于记录当前线程执行的位置,从而当线程被切换回来的时候能够知道该线程上次运行到哪儿了。

⚠️ 注意:程序计数器是唯一一个不会出现 OutOfMemoryError 的内存区域,它的生命周期随着线程的创建而创建,随着线程的结束而死亡。

2.2.Java虚拟机栈

JVM栈可以说是 JVM 运行时数据区域的一个核心,除了一些 Native 方法调用是通过本地方法栈实现的,其他所有的 Java 方法调用都是通过JVM栈来实现的(也需要和其他运行时数据区域比如程序计数器配合)。

从方法调用直至执行完成的过程,就对应着一个栈帧在 Java 虚拟机栈中入栈和出栈的过程。

局部变量表

局部变量表 主要存放了编译期可知的各种数据类型(boolean、byte、char、short、int、float、long、double)、对象引用(reference 类型,它不同于对象本身,可能是一个指向对象起始地址的引用指针,也可能是指向一个代表对象的句柄或其他与此对象相关的位置)

操作数栈

操作数栈 主要作为方法调用的中转站使用,用于存放方法执行过程中产生的中间计算结果。另外,计算过程中产生的临时变量也会放在操作数栈中。

动态链接

动态链接 主要服务一个方法需要调用其他方法的场景。Class 文件的常量池里保存有大量的符号引用,比如方法引用的符号引用。动态链接的作用就是为了将符号引用转换为调用方法的直接引用,这个过程也被称为 动态连接

方法返回地址

方法返回地址是当前方法执行完成后,线程应该跳转到的下一条指令的地址。这个返回地址实际上是保存在栈帧中的一个特殊位置,用于在方法执行完毕后恢复程序的执行流程。

2.3.本地方法栈

和虚拟机栈所发挥的作用非常相似,区别是:虚拟机栈为虚拟机执行 Java 方法 (也就是字节码)服务,而本地方法栈则为虚拟机使用到的 Native 方法服务。 在 HotSpot 虚拟机中和 Java 虚拟机栈合二为一。

本地方法被执行的时候,在本地方法栈也会创建一个栈帧,用于存放该本地方法的局部变量表、操作数栈、动态链接、出口信息。

方法执行完毕后相应的栈帧也会出栈并释放内存空间,也会出现 StackOverFlowErrorOutOfMemoryError 两种错误。

3.线程共享区域

3.1.堆

Java 虚拟机所管理的内存中最大的一块,Java 堆是所有线程共享的一块内存区域,在虚拟机启动时创建。此内存区域的唯一目的就是存放对象实例,几乎所有的对象实例以及数组都在这里分配内存。

Java 堆是垃圾收集器管理的主要区域,因此也被称作 GC 堆(Garbage Collected Heap)。从垃圾回收的角度,由于现在收集器基本都采用分代垃圾收集算法,所以 Java 堆还可以细分为:新生代和老年代;再细致一点有:Eden、Survivor、Old 等空间。进一步划分的目的是更好地回收内存,或者更快地分配内存。

JDK 8 版本之前,堆内存被通常分为下面三部分:

  1. 新生代(Young Generation)
  2. 老生代(Old Generation)
  3. 永久代(Permanent Generation)

JDK 8 版本之后 PermGen(永久代) 已被 Metaspace(元空间) 取代,元空间使用的是本地内存。

下图所示的 Eden 区、两个 Survivor 区都属于新生代,中间一层属于老年代,最下面一层属于元空间。

字符串常量池

字符串常量池 是 JVM 为了提升性能和减少内存消耗针对字符串(String 类)专门开辟的一块区域,主要目的是为了避免字符串的重复创建。

JDK1.7 之前,字符串常量池存放在永久代,JDK1.7之后字符串常量池和静态变量从永久代移动了 Java 堆中。

JDK 1.7 为什么要将字符串常量池移动到堆中?

主要是因为永久代(方法区实现)的 GC 回收效率太低,只有在整堆收集 (Full GC)的时候才会被执行 GC。Java 程序中通常会有大量的被创建的字符串等待回收,将字符串常量池放到堆中,能够更高效及时地回收字符串内存。

3.2.方法区

方法区是JVM规范定义的一块用于存储类的元数据、常量、静态变量、即时编译器(JIT编译器)编译后的代码等数据的内存区域。

当虚拟机要使用一个类时,它需要读取并解析 Class 文件获取相关信息,再将信息存入到方法区。 方法区会存储已被虚拟机加载的类信息、字段信息、方法信息、常量、静态变量、即时编译器编译后的代码缓存等数据。

方法区和永久代以及元空间是什么关系呢? 方法区和永久代以及元空间的关系很像 Java 中接口和类的关系,类实现了接口,这里的类就可以看作是永久代和元空间,接口可以看作是方法区,也就是说永久代以及元空间是 HotSpot 虚拟机对虚拟机规范中方法区的两种实现方式。并且,永久代是 JDK 1.8 之前的方法区实现,JDK 1.8 及以后方法区的实现变成了元空间。

为什么要将永久代 (PermGen) 替换为元空间 (MetaSpace) 呢?

1、永久代有 JVM 本身设置的固定大小上限,无法进行调整,而元空间使用的是本地内存,受本机可用内存的限制,虽然元空间仍旧可能溢出,但是比原来出现的几率会更小。

当元空间溢出时会得到如下错误:java.lang.OutOfMemoryError: MetaSpace

你可以使用 -XX:MaxMetaspaceSize 标志设置最大元空间大小,默认值为 unlimited,这意味着它只受系统内存的限制。-XX:MetaspaceSize 调整标志定义初始元空间大小,如果未指定此标志,则 Metaspace 将根据运行时的应用程序需求动态地重新调整大小。

2、元空间里面存放的是类的元数据,这样加载多少类的元数据就不由 MaxPermSize 控制了, 而由系统的实际可用空间来控制,这样能加载的类就更多了。

在JDK 1.8中,运行时常量池和字符串常量池逻辑上属于方法区,但是实际存放在堆内存中

运行时常量池

JVM的运行时常量池是方法区的一部分,它主要用于存放编译期生成的各种字面量符号引用。这些字面量和符号引用是在类加载的过程中,从Class文件的常量池中加载到方法区的运行时常量池中的。

字面量是源代码中的固定值的表示法,即通过字面我们就能知道其值的含义。字面量包括整数、浮点数和字符串字面量。常见的符号引用包括类符号引用、字段符号引用、方法符号引用、接口方法符号。

常量池会在类加载后存放到方法区的运行时常量池中。

运行时常量池的功能类似于传统编程语言的符号表,尽管它包含了比典型符号表更广泛的数据。

既然运行时常量池是方法区的一部分,自然受到方法区内存的限制,当常量池无法再申请到内存时会抛出 OutOfMemoryError 错误。

Class常量池: 可以理解为是Class文件中的资源仓库。
Class文件中除了包含类的版本、字段、方法、接口等描述信息外,还有就是常量池(constant pool table),用于存放编译器生成的各种字面量和符号引用
Class是用来保存常量的一个媒介场所,并且是一个中间场所。Class文件中的常量池部分的内容,会在运行期被运行时常量池加载进去。

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

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

相关文章

springboot船舶维保管理系统--论文源码调试讲解

第二章 相关技术 本次开发船舶维保管理系统使用的是Vue进行程序开发,船舶维保管理系统的数据信息选择MySQL数据库进行存放。 2.1 VUE介绍 Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue…

Unity入门1——基本操作

VIew工具 选中View工具后,按住鼠标左键,即可实现拖拽 按住Alt鼠标右键,移动鼠标即可实现缩放(或使用鼠标滚轮) Move工具 选中移动工具,即可对界面中的物品进行移动。快捷键W 快速定位物体 在层级管理器中…

回溯分割+子集篇--代码随想录算法训练营第二十二天| 131.分割回文串,93.复原IP地址,78.子集,90.子集II

131.分割回文串 题目链接:. - 力扣(LeetCode) 讲解视频:131.分割回文串 题目描述: 给你一个字符串 s,请你将 s 分割成一些子串,使每个子串都是回文串 。返回 s 所有可能的分割方案。 示例 …

2.3 Python 基本运算符

欢迎来到我的博客,很高兴能够在这里和您见面!欢迎订阅相关专栏: 工💗重💗hao💗:野老杂谈 ⭐️ 全网最全IT互联网公司面试宝典:收集整理全网各大IT互联网公司技术、项目、HR面试真题.…

C++ STL专题 list的讲解

目录 1.list的介绍和使用 1.1 list的介绍 1.2 list的使用 1.2.1 list的构造 1.2.2 list iterator的使用 1.2.3 list capacity 1.2.4 list element access 1.2.5 list modifiers 1.list的介绍和使用 1.1 list的介绍 1.list是可以在常数范围内任意位置进行插入和删除的序…

git系统学习

git系统学习 git命令行获取git 版本号 创建初始版本库创建git库初始化用户名和密码查看用户名和邮箱修改用户名和密码 将文件添加到版本库中删除暂存文件提交代码查看提交信息查看更加详细的信息查看提交差异版本库内文件的删除和重命名删除库里的文件重命名库里的文件 打标签查…

【RunnerGo】离线安装成功版本

目录 一、下载 二、解压安装包 三、修改安装配置 3.1 编辑修改安装参数(我没有改,默认安装即可) 3.2 安装目录结构说明 四、执行安装 五、检查服务并使用 六、访问 前言:最近在调研一个新工具,发现RunnerGo&…

文章解读与仿真程序复现思路——电网技术EI\CSCD\北大核心《考虑通信-物理耦合的有源配网故障后协调恢复策略 》

本专栏栏目提供文章与程序复现思路,具体已有的论文与论文源程序可翻阅本博主免费的专栏栏目《论文与完整程序》 论文与完整源程序_电网论文源程序的博客-CSDN博客https://blog.csdn.net/liang674027206/category_12531414.html 电网论文源程序-CSDN博客电网论文源…

SpringBoot banner 推荐

看看我这个怎么样 效果图 在resources下面创建一个banner.txt,把下面代码放到进去就可以用了 ${AnsiColor.GREEN} Application Version: ${ruoyi.version} Spring Boot Version: ${spring-boot.version}69696969 696969696969 696969 …

Facebook的技术创新:如何改变社交网络的面貌

Facebook作为全球最大的社交网络平台之一,一直在不断推动技术创新,以提升用户体验和社交互动质量。这些技术创新不仅改变了人们的社交方式,也深刻影响了整个社交网络的面貌。 人工智能驱动的内容推荐 Facebook利用人工智能(AI&am…

深圳市光明区副区长彭颖一行莅临立仪科技参观考察

2024年8月5日上午,‌深圳市光明区彭颖副区长一行领导莅临深圳立仪科技有限公司调研指导工作,深圳市智能传感行业协会执行会长姜勇以及协会秘书长张喻陪同调研。我公司总经理刘杰波、以及各部门负责人陪同参加。 彭颖副区长一行领导在刘总的接待和讲解下&…

vue实现页面中点击预览报告,实现将vue组件变成pdf文件进行弹窗展示

一.实现效果 页面中点击预览报告,实现将vue组件变成pdf文件进行弹窗展示 定义的方法文件 import html2canvas from "html2canvas"; import jsPDF, { RGBAData } from "jspdf";/** a4纸的尺寸[595.28,841.89], 单位毫米 */ const [PAGE_WIDT…

微深节能 环形运动机械定位控制系统 格雷母线

格雷母线定位系统作为一种高精度、无磨损的非接触式位置检测系统,特别适用于环形运动机械的定位控制。 一、格雷母线定位系统的概述 格雷母线定位系统主要由一台地面电气柜、一台车载电气柜、格雷母线以及天线箱等组成。其核心部件是格雷母线,一种特殊的…

深度学习人脸表情识别结课作业留存

0.前言 大三下学期学习了深度学习神经网络的课程,老师留下了人脸表情识别的结课作业,在网上找到了一个想相对不错的开源项目作为基础完成了本次的结课作业。 1.项目链接 Challenges in Representation Learning: Facial Expression Recognition Chall…

运动耳机怎么选?来看看奥运冠军喜欢的运动耳机!

在奥运的竞技舞台上,每一次心跳的跃动都是对自我极限的勇敢挑战,运动员的每一个动作背后,都承载着不懈的努力与对梦想的执着追求。如今,运动科技正以前所未有的速度改变着我们的运动方式,一款优秀的运动耳机成为了连接…

Prompt Fuzzer:用于增强 GenAI 应用程序的开源工具

Prompt Fuzzer 是一个开源工具,可以评估GenAI应用程序的系统提示针对基于动态 LLM 的威胁的安全性。 Prompt Fuzzer 功能: 1. 模拟十几种类型的 GenAI 攻击。 2. 该工具会根据系统提示自动进行情境化,针对与 GenAI 应用程序相关的特定主题或行…

【Python机器学习】回归——用线性回归找到最佳拟合直线

线性回归的优缺点: 优点:结果易于理解,计算上不复杂 缺点:对非线性的数据拟合不好 使用数据类型:数值型和标称型数据。 回归的目的是预测数值型的目标值。最直接的办法是依据输入写出一个目标值的计算公式。例如预测汽…

【C语言】预处理详解(上)

文章目录 前言1. 预定义符号2. #define 定义常量3. #define定义宏4. 带有副作用的宏参数5. 宏替换的规则 前言 在讲解编译和链接的知识点中,我提到过翻译环境中主要由编译和链接两大部分所组成。 其中,编译又包括了预处理、编译和汇编。当时&#xff0c…

【Windows系统开机后识别不到屏幕适配的分辨率导致屏幕无法点亮的解决办法】

问题原因分析: 屏幕驱动板出现故障,驱动出现缺失,未对主板系统进行适配兼容。使用的屏幕分辨率非常小众,系统中没有这个分辨率,识别不到屏幕适配的分辨率后导致屏幕无法点亮。 解决方法: 找主板厂家增加…

CVE-2022-33891漏洞复现

简介 Spark 是用于大规模数据处理的统一分析引擎。它提供了 Scala、Java、Python 和 R 中的高级 API,以及支持用于数据分析的通用计算图的优化引擎。它还支持一组丰富的高级工具,包括用于 SQL 和 DataFrames 的 Spark SQL、用于 Pandas 工作负载的 Spar…