JVM系列 运行时数据区

系列文章目录

第一章 运行区实验


文章目录

  • 系列文章目录
  • 前言
  • 一、堆(Heap)
    • 1.1、新生代/Young区
      • 1.1.1、Eden区
      • 1.1.2、Survival区
    • 1.2、年老代(old区)
  • 二、虚拟机栈(Stack)
    • 2.1、栈顶缓存技术
    • 2.2、溢出
    • 2.3、栈帧
      • 2.3.1、局部变量表(local variables)
      • 2.3.2、操作数栈(Operand Stack LIFO)
      • 2.3.3、动态链接
      • 2.3.4、方法返回地址
      • 2.3.5、额外信息
  • 三、方法区(MetaData Space)
    • 3.1、方法区和永久代的关系
  • 四、本地方法栈(Native Method Stacks)
  • 五、程序计数器
  • 六、直接内存(Direct Memory)
  • 总结


前言

JVM(Java虚拟机)运行区是Java程序在运行过程中被JVM所管理的内存区域。它包括了Java程序运行时的堆(Heap)、栈(Stack)、方法区(Method Area)、本地方法栈(Native Method Stacks)、程序计数器和直接内存(Direct Memory)等部分。
在这里插入图片描述


一、堆(Heap)

堆(Heap)是Java程序运行时用于动态分配内存的区域,也是Java垃圾收集器进行垃圾回收的主要区域。堆内存被所有线程共享。

以JDK8为例,堆(Heap)用来存放对象,几乎所有(逃逸分析技术,栈上分配、标量替换)对象都在堆上分配,将Java堆细分的目的只是为了更好地回收内存,或者更快地分配内存,堆中没有内存分配对象,并且无法扩展时,会抛出OutOfMemoryError异常。

堆(Heap)一般管理新生代/Young区 、年老代(old区) 、String字符串常量池。

1.1、新生代/Young区

新生代里包含Eden区 与 Survival区2个区。

1.1.1、Eden区

Eden区位于Java堆的年轻代,是新对象分配内存的地方,由于堆是所有线程共享的,因此在堆上分配内存需要加锁。而Sun JDK为提升效率,会为每个新建的线程在Eden上分配一块独立的空间由该线程独享,这块空间称为TLAB(Thread Local Allocation Buffer)。在TLAB上分配内存不需要加锁,因此JVM在给线程中的对象分配内存时会尽量在TLAB上分配。如果对象过大或TLAB用完,则仍然在堆上进行分配。如果Eden区内存也用完了,则会进行一次Minor GC(young GC)。

1.1.2、Survival区

Survival区与Eden区相同都在Java堆的年轻代。Survival区有两块,一块称为from区,另一块为to区,这两个区是相对的,在发生一次Minor GC后,from区就会和to区互换。在发生Minor GC时,Eden区和Survival from区会把一些仍然存活的对象复制进Survival to区,并清除内存。Survival to区会把一些存活得足够旧的对象移至年老代。

1.2、年老代(old区)

年老代里存放的都是存活时间较久的,大小较大的对象,因此年老代使用标记整理算法。当年老代容量满的时候,会触发一次Major GC(full GC),回收年老代和年轻代中不再被使用的对象资源

二、虚拟机栈(Stack)

每个线程在创建时都会创建一个私有的JVM栈。每个方法执行的时候都会创建一个栈帧,用于存储局部变量、操作数栈、常量池引用等信息。如下图,栈帧1、栈帧2、栈帧3、栈帧N。
在这里插入图片描述

2.1、栈顶缓存技术

解释执行状态下,将访问最频繁的数据(程序计数器、栈顶)缓存在物理CPU的寄存器中,以此降低对内存的读/写次数,提升执行引擎的执行效率。

2.2、溢出

如果线程请求的栈深度大于虚拟机所允许深度,将抛出StackOverflowError异常;如果Java虚拟机栈容量可以动态扩展 ,当栈扩展时无法申请到足够的内存会抛出OutOfMemoryError异常。

发生StackOverflowError异常,使用死循环递归代码可以复现。
在这里插入图片描述
可以使用参数-Xss选项来设置线程的最大栈空间,例如-Xss265k

2.3、栈帧

栈的存储单位为栈帧,线程上正在执行的一个方法对应一个栈帧,栈帧是一个内存区块,是一个数据集,维系着方法执行过程中的各种数据信息。

每个栈帧包含五部分,分别包括局部变量表、操作数栈、动态链表(指向运行时常量池的方法引用)、方法返回地址和一些额外信息。
在这里插入图片描述

2.3.1、局部变量表(local variables)

  • 局部变量表定义为一个数字数组,主要用于存储方法参数和定义在方法体内的局部变量,这些数据类型包括各种基本数据类型、对象引用(reference),以及returnAddress类型。

  • 由于局部变量表是线程的私有数据,不存在线程的安全问题

  • 局部变量表所需容量大小在编译器确定下来的,并保存在方法的Code属性的maximum local variables数据项中。在方法运行期间是不会改变局部变量表的大小的。

  • 局部变量表的变量只在当前方法调用中有效的,当方法调用结束后,随着方法栈帧的消耗,局部变量表也会随之销毁。

  • 局部变量表的最基本存储单位是Slot(变量槽),32位以内的类型只占用一个slot(包括returnAddress类型,引用类型),64位的类型(long和double)占用两个slot。

  • 每一slot都分配一个访问索引,占用两个slot的变量,只需要使用前一个索引即可

  • 构造方法或者实例方法(非static),该对象引用this将会存放在index为0的slot处

  • 局部变量表的变量也是重要的垃圾回收根节点,只要被局部变量表中直接或间接引用的对象都不会被回收。

2.3.2、操作数栈(Operand Stack LIFO)

  • 编译后 .Class文件的Code属性的max_stacks数据记录操作数栈的最大深度
  • 操作数栈,在方法执行过程中,根据字节码指令,往栈中写入数据或提取数据,即入栈或者出栈,使用数组实现
  • 操作数栈,主要用于保存计算过程的中间结果,同时作为计算过程中变量临时的存储空间。

2.3.3、动态链接

运行期间把常量池中的符号引用转换成直接引用的过程,叫做动态链接;
每个栈帧都包含一个指向运行时常量池中该栈帧所属方法的引用,持有这个引用是为了支持方法调用过程中的动态链接。

2.3.4、方法返回地址

方法返回地址存储的是调用该方法的pc寄存器的值。方法正常退出时,调用者的pc计数器的值作为返回地址,即调用该方法的指令的下一条指令的地址。

2.3.5、额外信息

Java虚拟机规范,允许虚拟机实现,在栈帧之中增加一些规范里没有描述的信息,例如与调试、性能收集相关的信息。

三、方法区(MetaData Space)

方法区(MetaData Space 元空间)/Non-Heap,用于存储已被JVM加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。
在这里插入图片描述

3.1、方法区和永久代的关系

在JDK1.8之前,习惯把方法区称为“永久代”。HotSpot 虚拟机在1.7之前使用永久代来管理(实现)方法区,使得jvm的垃圾回收器能像管理堆内存一样来管理永久代这部分内存,而不用专门为方法区编写内存管理代码。但这种设计使得虚拟机更容易出现内存溢出问题,而不像J9和JRockit只要没有触碰到进程可用内存的上限(32位4GB),就没有问题。
JDK1.7把原本放在永久代的字符串常量池、静态变量等移出(主要剩余类型信息)
JDK1.8完全废弃了永久代的概念,改用与JRockit、J9一样,在本地内存中实现的元空间方法区无法满足新的内存分配需求时,将抛出OutOfMemoryError异常。

四、本地方法栈(Native Method Stacks)

Native Method Stacks 为虚拟机使用到的本地(Native)方法服务,本地方法栈也会在栈深度溢出或者栈扩展失败时分别抛出StackOverflowError和OutOfMemoryError异常。

五、程序计数器

程序计数器,当前线程所执行的字节码的行号指示器,字节码解释器工作时,通过改变计数器的值,执行下一条指令,此内存是JVM规范中唯一一个没有OutOfMemoryError的区域。

六、直接内存(Direct Memory)

DM并不是虚拟机运行时数据区的一部分,也不是《Java虚拟机规范》中定义的内存区域。但是这部分内存也被频繁地使用,而且也可能导致OutOfMemoryError异常出现,例如:NIO 中的 DirectByteBuffer 直接操作堆外内存,避免在Java堆和Native堆中来回复制数据。

同时也可以关注零拷贝(DMA)技术的应用。


总结

这些内存区域的管理和优化对于Java程序的性能和可靠性至关重要。

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

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

相关文章

82 # koa-bodyparser 中间件的使用以及实现

准备工作 安装依赖 npm init -y npm i koakoa 文档:https://koajs.cn/# koa 中不能用回调的方式来实现,因为 async 函数执行的时候不会等待回调完成 app.use(async (ctx, next) > {console.log(ctx.path, ctx.method);if (ctx.path "/login…

C高级day4

一、实现一个对数组求和的函数,数组通过实参传递给函数 二、写一个函数,输出当前用户的uid和gid,并使用变量接收结果 三、XMind思维导图

JavaScript学习--Day04

元字符 边界符: /^/:以什么开头 /$/:以什么结尾 量词: 预定义类:

vs2019配置sfml外部库出现的问题

问题描述 在debug模式下程序正常运行,在release模式中报错 解决 C/C Windows环境下 boost 安装使用教程 Debug 通常称为调试版本,它包含调试信息,并且不作任何优化,便于程序员调试程序。 Release:Release通常称为发…

基于springboot+vue的实验室耗材管理系统(前后端分离)

博主主页:猫头鹰源码 博主简介:Java领域优质创作者、CSDN博客专家、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战 主要内容:毕业设计(Javaweb项目|小程序等)、简历模板、学习资料、面试题库、技术咨询 文末联系获取 项目介绍…

【业务功能篇105】 微服务-springcloud-springboot-电商订单模块--秒杀服务-定时任务【上篇】

秒杀服务 一、商品上架 秒杀活动的结构图 通过定时任务触发: 定时任务由spring提供,需要通过注解开启,这里通过定义一个配置类,注入spring,对其配置类进行相应的注解,当然也可以注解放在我们的服务启动类上cron表达…

Windows wsl2安装Ubuntu

wsl(Windows Subsystem for Linux)即适用于Windows的Linux子系统,是一个实现在Windows 10 / 11上运行原生Linux的技术。 wsl2 为其迭代版本,可以更好的在Windows上运行Linux子系统。 这里以 Windows 11 安装Ubuntu作为示例。 开启…

提升效率:PostgreSQL准确且快速的数据对比方法

作为一款强大而广受欢迎的开源关系型数据库管理系统,PostgreSQL 在数据库领域拥有显著的市场份额。其出色的可扩展性、稳定性使其成为众多企业和项目的首选数据库。而在很多场景下(开发|生产环境同步、备份恢复验证、数据迁移、数据合并等)&a…

“JSR303和拦截器在Java Web开发中的应用与实践“

目录 引言JSR303什么是JSR303?为什么要使用JSR303?常用注解快速入门JSR303 拦截器什么是拦截器拦截器与过滤器应用场景快速入门拦截器 总结 引言 在Java Web开发过程中,我们经常会遇到需要对输入数据进行验证和处理,同时需要对请求进行拦截与控制的需…

PyTorch深度学习实践1——线性回归和Logistic回归

PyTorch的风格 准备数据集使用类设计模型计算损失函数和优化器训练【前向、反向和更新】 线性回归 import torch# 准备数据集 # x,y是矩阵,3行1列 也就是说总共有3个数据,每个数据只有1个特征 x_data torch.tensor([[1.0], [2.0], [3.0]]) y_data to…

Modelsim仿真问题解疑二:ERROR: [USF-ModelSim-70]

现象:在Vivado中已配置modelsim为仿真工具后,运行仿真,报错USF-ModelSim-70和ERROR: [Vivado 12-4473] 详细报错内容如下 ERROR: [USF-ModelSim-70] compile step failed with error(s) while executing C:/Users/ZYP_PC/Desktop/verilog_t…

python趣味编程-恐龙克隆游戏

Python 中使用 Turtle 的恐龙克隆游戏免费源代码 使用 Turtle 的恐龙克隆游戏是一个用Python编程语言编码的桌面游戏应用程序。该项目包含在 Chrome 浏览器中克隆实际恐龙游戏的多种功能。该项目可以使正在修读 IT 相关课程的学生受益。这个应用程序非常有趣,可以帮助您学习创…

显示器配置信息删除

显示器配置信息删除 1 介绍2 操作参考 1 介绍 笔记本屏幕坏了,手头的拓展显示器都是配置成拓展显示,需要先找一台没配置过的显示器将系统中显示器配置信息删除,这样就能复制屏幕显示到拓展屏幕上了。 2 操作 Windows 的显示器配置位于注册…

算法AB实验平台进化历程和挑战

1 AB 平台简介 AB 实验平台这几年在互联网公司得到了越来越广泛的应用,采用 AB 实验来评估产品和技术迭代效果也成为主流的业务新功能效果评估方式,数据驱动的文化在这几年得到了不少公司的广泛的认同,通过数据和指标来说明产品效果也得到了…

大数据组件-Flink环境搭建

🥇🥇【大数据学习记录篇】-持续更新中~🥇🥇 个人主页:beixi 本文章收录于专栏(点击传送):【大数据学习】 💓💓持续更新中,感谢各位前辈朋友们支持…

Nacos使用和注册部分源码介绍

Nacos简单介绍 Nacos致力于帮助您发现、配置和管理微服务。Nacos提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据及流量管理。Nacos帮助您更敏捷和容易地构建、交付和管理微服务平台。Nacos是构建以“服务”为中心的现代应用架构 (例…

NLP信息抽取全解析:从命名实体到事件的PyTorch实战指南

目录 引言背景和信息抽取的重要性文章的目标和结构 信息抽取概述什么是信息抽取信息抽取的应用场景信息抽取的主要挑战 实体识别什么是实体识别实体识别的应用场景PyTorch实现代码输入、输出与处理过程 关系抽取什么是关系抽取关系抽取的应用场景PyTorch实现代码输入、输出与处…

超高真空度精密控制解决方案设计中百度“文心一言”的具体应用

摘要:本文采用国产版本ChatGPT百度“文心一言”作为一种辅助工具,针对超高真空度精密控制装置的开发进行了初期的技术路线设计,对话调研的重点是了解可调节式微流量进气阀门和可用于连接非线性输出信号型真空计的PID控制器。总体而言&#xf…

Google Hacking搜索

Google Hacking概述 GoogleHacking基本用法逻辑或OR逻辑与And逻辑非NOT完整匹配 GoogleHacking高级用法sitefiletypeinurlintitleintext Google Hacking DataBaseGoogle Hacking概述 GoogleHacking:利用搜索引擎有争对性的搜索信息来对网络入侵的技术和行为。搜索引…

异步请求库的实际应用案例:爬取豆瓣经典电影

在日常爬虫过程中,你有没有遇到过需要爬取大量数据的情况,但是传统的同步请求方式让您等得焦头烂额? 这个问题的根源在于传统的同步请求方式。当我们使用同步请求时,程序会一直等待服务器的响应,直到数据返回后才能继续…