Java虚拟机JVM-运行时数据区域说明

news2024/10/7 17:35:29

及时编译器

HotSpot虚拟机中含有两个即时编译器,分别是编译耗时短但输出代码优化程度较低的客户端编译器(简称为C1)以及编译耗时长但输出代码优化质量也更高的服务端编译器(简称为C2),通常它们会在分层编译机制下与解释器互相配合来共同构成HotSpot虚拟机的执行子系统。

自JDK 10起,HotSpot中又加入了一个全新的即时编译器:Graal编译器, Graal编译器是以C2编译器替代者的身份登场的。

运行时数据区域

1、程序计数器

程序计数器(Program Counter Register)是一块较小的内存空间,它可以看作是当前线程所执行的字节码的行号指示器,存储当前线程执行的字节码的偏移量在Java虚拟机的概念模型里,字节码解释器工作时就是通过改变这个计数器的值来选取下一条需要执行的字节码指令,它是程序控制流的指示器,分支、循环、跳转、异常处理、线程恢复等基础功能都需要依赖这个计数器来完成。

由于Java虚拟机的多线程是通过线程轮流切换、分配处理器执行时间的方式来实现的,在任何一个确定的时刻一个处理器(对于多核处理器来说是一个内核)都只会执行一条线程中的指令。因此,为了线程切换后能恢复到正确的执行位置,每条线程都需要有一个独立的程序计数器,各条线程之间计数器互不影响,独立存储,我们称这类内存区域为“线程私有”的内存。

2、Java虚拟机栈

与程序计数器一样,Java虚拟机栈(Java Virtual Machine Stack)也是线程私有的,它的生命周期与线程相同。虚拟机栈描述的是Java方法执行的线程内存模型:每个方法被执行的时候,Java虚拟机都会同步创建一个栈帧(Stack Frame)用于存储局部变量表、操作数栈、动态连接、方法出口等信息。每一个方法被调用直至执行完毕的过程,就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。
      经常有人把Java内存区域笼统地划分为堆内存(Heap)和栈内存(Stack),这种划分方式直接继承自传统的C、C++程序的内存布局结构,在Java语言里就显得有些粗糙了,实际的内存区域划分要比这更复杂。不过这种划分方式的流行也间接说明了程序员最关注的、与对象内存分配关系最密切的区域是“堆”和“栈”两块。 “栈”通常就是指这里讲的虚拟机栈,或者更多的情况下只是指虚拟机栈中局部变量表部分


   局部变量表存放了编译期可知的各种Java虚拟机基本数据类型(boolean、byte、char、short、int、float、long、double)、对象引用(reference类型,它并不等同于对象本身,可能是一个指向对象起始地址的引用指针,也可能是指向一个代表对象的句柄或者其他与此对象相关的位置)和returnAddress类型(指向了一条字节码指令的地址)。


这些数据类型在局部变量表中的存储空间以局部变量槽(Slot)来表示,其中64位长度的long和double类型的数据会占用两个变量槽,其余的数据类型只占用一个。局部变量表所需的内存空间在编译期间完成分配,当进入一个方法时,这个方法需要在栈帧中分配多大的局部变量空间是完全确定的,在方法运行期间不会改变局部变量表的大小。请读者注意,这里说的“大小”是指变量槽的数量,虚拟机真正使用多大的内存空间(譬如按照1个变量槽占用32个比特、64个比特,或者更多)来实现一个变量槽,这是完全由具体的虚拟机实现自行决定的事情。

补充--栈帧:

栈帧中存储的是方法所需的数据,指令、返回地址等信息,虚拟机栈的结构如下:

 (1)、虚拟机栈是基于线程的:哪怕你只有一个 main() 方法,也是以线程的方式运行的。在线程的生命周期中,参与执行的方法栈帧会频繁地入栈和出栈,虚拟机栈的生命周期是和线程一样的。
(2)、栈大小:每个虚拟机栈的大小缺省为 1M,
(3)、堆栈溢出:栈帧深度压栈但并不出栈,导致栈空间不足,抛出java.lang.StackOverflowError ,典型的就是递归调用,
(4)、栈帧的组成:栈帧大体都包含四个区域:(局部变量表、操作数栈、动态连接、返回地址),如下图所示:

(1)、局部变量表:存放我们的局部变量的(方法内的变量)。首先它是一个32位的长度,主要存放我们的 Java的八大基础数据类型,一般 32 位就可以存放下,如果是 64 位的就使用高低位占用两个也可以存放下,如果是局部变量是一个对象,存放它的一个引用地址即可。
(2)、操作数栈:存放 java 方法执行的操作数的,它也是一个栈,操作的的元素可以是任意的 java数据类型,一个方法刚刚开始的时候操作数栈为空,操作数栈本质上是JVM执行引擎的一个工作区,方法在执行,才会对操作数栈进行操作。
(3)、动态链接:Java 语言特性多态
(4)、完成出口:正常返回(调用程序计数器中的地址作为返回)、异常的话(通过异常处理器表<非栈帧中的>来确定) 

3 本地方法栈

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

4 Java堆

对于Java应用程序来说,Java堆(Java Heap)是虚拟机所管理的内存中最大的一块。Java堆是被所有线程共享的一块内存区域,在虚拟机启动时创建。此内存区域的唯一目的就是存放对象实例,Java世界里“几乎”所有的对象实例都在这里分配内存。
   Java堆是垃圾收集器管理的内存区域,因此一些资料中它也被称作“GC堆”(Garbage Collected Heap,幸好没翻译成“垃圾堆”)。 

(1) 、堆被划分为新生代和老年代( Tenured ),
(2) 、新生代与老年代的比例的值为 1:2 ,该值可以通过参数 –XX:NewRatio 来指定 。
(3) 、新生代又被进一步划分为 Eden Survivor 区, Survivor From Survivor 和 To Survivor 组成, eden from to 的大小比例为: 8 1 1 ; 可通过参数 - XX:SurvivorRatio 来指定。

 

5 方法区

方法区(Method Area)与Java堆一样,是各个线程共享的内存区域,它用于存储已被虚拟机加载的类型信息、常量、静态变量、即时编译器编译后的代码缓存等数据。虽然《Java虚拟机规范》中把方法区描述为堆的一个逻辑部分,但是它却有一个别名叫作“非堆”(Non-Heap),目的是与Java堆区分开来。

方法区中存储的信息大致可分以下两类:
(1) 、类信息:主要指类相关的版本、字段、方法、接口描述、引用等
(2) 、运行时常量池:编译阶段生成的常量与符号引用、运行时加入的动态变量

5.1 运行时常量池

运行时常量池(Runtime Constant Pool)是方法区的一部分Class文件中除了有类的版本、字段、方法、接口等描述信息外,还有一项信息是常量池表(Constant Pool Table),用于存放编译期生成的各种字面量与符号引用,这部分内容将在类加载后存放到方法区的运行时常量池中

6 直接内存

直接内存(Direct Memory)并不是虚拟机运行时数据区的一部分,也不是《Java虚拟机规范》中定义的内存区域。但是这部分内存也被频繁地使用,而且也可能导致OutOfMemoryError异常出现,所以我们放到这里一起讲解。

本机直接内存的分配不会受到Java堆大小的限制,但是,既然是内存,则肯定还是会受到本机总内存(包括物理内存、SWAP分区或者分页文件)大小以及处理器寻址空间的限制,一般服务器管理员配置虚拟机参数时,会根据实际内存去设置-Xmx等参数信息,但经常忽略掉直接内存,使得各个内存区域总和大于物理内存限制(包括物理的和操作系统级的限制),从而导致动态扩展时出现OutOfMemoryError异常

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

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

相关文章

【Linux】手把手教你在CentOS上使用docker 安装MySQL8.0

文章目录前言一. docker的安装1.1 从阿里下载repo镜像1.2 安装docker1.3 启动docker并查看版本二. 使用docker安装MySQL8.02.1 拉取MySQL镜像2.2 创建容器2.3 操作MySQL容器2.4 远程登录测试总结前言 大家好&#xff0c;又见面了&#xff0c;我是沐风晓月&#xff0c;本文主要…

docker系列1:docker安装

传送门 docker官网地址&#xff1a; Docker: Accelerated, Containerized Application Development 安装地址&#xff1a;Install Docker Engine docker hub地址 docker hub&#xff1a;Docker 安装步骤 前置条件 由于安装docker&#xff0c;需要根据操作系统版本选择…

设计模式(只谈理解,没有代码)

1.什么是设计模式设计模式&#xff0c;是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性、程序的重用性。2.为什么要学习设计模式看懂源代码&#xff1a;如果你不懂设计模式去看Jd…

【react全家桶】生命周期

文章目录04 【生命周期】1.简介2.初始化阶段2.1 constructor2.2 componentWillMount&#xff08;即将废弃&#xff09;2.3 static getDerivedStateFromProps&#xff08;新钩子&#xff09;2.4 render2.5 componentDidMount2.6 初始化阶段总结3.更新阶段3.1 componentWillRecei…

2023最新版本RabbitMQ的持久化和简单使用

上节讲了 RabbitMQ下载安装教程 &#xff0c; 本节主要介绍RabbitMQ的持久化和简单使用。 一、RabbitMQ消息持久化 当处理一个比较耗时得任务的时候&#xff0c;也许想知道消费者&#xff08;consumers&#xff09;是否运行到一半就挂掉。在当前的代码中&#xff0c;当RabbitM…

如何在本地跑FuzzBench的实验

概述 FuzzBench是谷歌做的一个评估模糊测试的benchmark&#xff0c;主要目的是为了评测覆盖率导向模糊测试工具能达到多少覆盖率&#xff0c;能够发现多少漏洞。本文主要介绍如何在本地运行fuzzbench的实验。当然也可以用谷歌的云服务来跑&#xff0c;具体教程在这&#xff1a…

计算机底层:BDC码

计算机底层&#xff1a;BDC码 BDC码的作用&#xff1a; 人类喜欢十进制&#xff0c;而机器适合二进制&#xff0c;因此当机器要翻译二进制给人看时&#xff0c;就会进行二进制和十进制的转换&#xff0c;而常规的转换法&#xff08;k*位权&#xff09;太麻烦。因此就出现了不同…

基本类型、包装类型、引用类型、String等作为实参传递后值会不会改变?

看了半天帖子&#xff0c;讲得乱七八糟&#xff0c;坑死了 [1] 先说结论 基本类型、包装类型、String类型作为参数传递之后&#xff0c;在方法里面修改他们的值&#xff0c;原值不会改变&#xff01;引用类型不一定&#xff0c;要看是怎么修改它的。 [2] 为什么基本类型、包装类…

程序设计语言-软件设计(二十一)

数据结构与算法&#xff08;二十&#xff09;快速排序、堆排序(四)https://blog.csdn.net/ke1ying/article/details/129269655 这篇主要讲的是 编译与解释、文法、正规式、有限自动机、表达式、传值与传址、多种程序语言特点。 编译的过程 解释型 和 编译型 编译型过程&#…

【IDEA】IDEA使用有道翻译引擎—详细配置步骤

目录 前言 步骤一&#xff1a;下载翻译工具Translate 步骤二&#xff1a;注册登录有道云平台 步骤三&#xff1a;配置有道翻译 前言 2022年10月 谷歌翻译已经不在中国了&#xff0c;所以IDEA配置谷歌翻译会出错。 步骤一&#xff1a;下载翻译工具Translate 打开idea设置set…

c语言经典例题-选择结构程序设计进阶

(创作不易&#xff0c;感谢有你&#xff0c;你的支持&#xff0c;就是我前行的最大动力&#xff0c;如果看完对你有帮助&#xff0c;请留下您的足迹&#xff09; 目录 快递费用计算&#xff1a; 题目&#xff1a; 代码思路&#xff1a; 代码表示&#xff1a; 计算一元二…

Java奠基】数组的讲解与使用

目录 数组概述 数组的定义与初始化 数值遍历 数组的常见操作 数组内存图 数组概述 数组是一种容器&#xff0c;可以用来存储同种数据类型的多个值&#xff0c;数组容器在存储数据的时候&#xff0c;需要结合隐式转换考虑。例如&#xff1a;int类型的数组容器不能存放取值…

191、【动态规划】AcWing ——AcWing 900. 整数划分:完全背包解法+加减1解法(C++版本)

题目描述 参考文章&#xff1a;900. 整数划分 解题思路 因为本题中规定了数字从大到小&#xff0c;其实也就是不论是1 2 1 4&#xff0c;还是2 1 1 4&#xff0c;都会被看作是2 1 1 4这一种情况&#xff0c;因此本题是在遍历中不考虑结果顺序。 背包问题中只需考虑…

mysql一条语句的写入原理

mysql写入原理 我们知道在mysql数据库最核心的大脑就是执行引擎&#xff1b; 其中的默认引擎Innodb在可靠执行和性能中做出来平衡&#xff1b; innodb支持在事务控制、读写效率&#xff0c;多用户并发&#xff0c;索引搜索方面都表现不俗&#xff1b; innodb如何进行数据写入…

MYSQL性能分析,Explain,Show Profile

文章目录一、MYSQL常见瓶颈二、ExplainExplain是什么三、Show Profile四、慢查询日志和全局查询日志一、MYSQL常见瓶颈 CPU&#xff1a; CPU饱和IO&#xff1a;磁盘IO速度过慢。服务器的硬件性能瓶颈。 二、Explain Explain是什么 使用explain关键字可以模拟优化器执行sql查…

YApi分析从NoSQL注入到RCE远程命令执行.md

0x00 前提 这个是前几个月的漏洞&#xff0c;之前爆出来发现没人分析就看了一下&#xff0c;也写了一片 Nosql注入的文章&#xff0c;最近生病在家&#xff0c;把这个写一半的完善一下发出来吧。 0x01 介绍 YApi是一个可本地部署的、打通前后端及QA的、可视化的接口管理平台…

【C++】命名空间

&#x1f3d6;️作者&#xff1a;malloc不出对象 ⛺专栏&#xff1a;C的学习之路 &#x1f466;个人简介&#xff1a;一名双非本科院校大二在读的科班编程菜鸟&#xff0c;努力编程只为赶上各位大佬的步伐&#x1f648;&#x1f648; 目录前言一、命名空间产生的背景二、命名空…

【一天时间|简历模板】世界上最好的前端简历

一天时间系列文章是博主精心整理的面试热点问题和难点问题&#xff0c;吸收了大量的技术博客与面试文章&#xff0c;总结多年的面试经历&#xff0c;带你快速并高效地审视前端面试知识。直击技术痛点&#xff0c;主动出击&#xff0c;精密打击&#xff0c;这才是面试拿到高薪的…

网络基础知识(IP地址、TCP协议/IP协议、UDP协议、三次握手,四次挥手的过程、端口等的概念)

TCP/IP 协议 首先给大家说明的是&#xff0c;TCP/IP 协议它其实是一个协议族&#xff0c;包含了众多的协议&#xff0c;譬如应用层协议 HTTP、FTP、MQTT…以及传输层协议 TCP、UDP 等这些都属于 TCP/IP 协议。 所以&#xff0c;我们一般说 TCP/IP 协议&#xff0c;它不是指某…

unity-与js交互

title: unity-与js交互 categories: Unity3d tags: [unity, js, web, h5] date: 2023-03-05 00:09:52 comments: false mathjax: true toc: true unity-与js交互 前篇 官方 WebGL&#xff1a;与浏览器脚本交互 - https://docs.unity3d.com/cn/2021.1/Manual/webgl-interacting…