JVM:运行时数据区

news2024/11/15 3:45:08

文章目录

  • 一、总览
  • 二、程序计数器
    • 1、介绍
    • 2、程序计数器在运行中会出现内存溢出吗?
  • 三、栈
    • 1、介绍
    • 2、栈帧的组成部分
      • (1)局部变量表
      • (2)操作数栈
      • (3)帧数据
      • (3)栈内存溢出
      • (4)栈的默认大小
    • 3、本地方法栈
  • 四、堆内存
    • 1、介绍
    • 2、是不是当used=total=max的时候,堆内存就溢出了?
    • 3、堆大小
  • 五、方法区
    • 1、介绍
    • 2、ByteBuddy框架的基本使用方法
    • 3、字符串常量池
  • 六、直接内存
    • 1、介绍
    • 2、直接内存中创建数据
    • 3、设置大小

一、总览

  • Java虚拟机在运行Java程序过程中管理的内存区域,称之为运行时数据区。
  • 《Java虚拟机规范》中规定了每一部分的作用。
    在这里插入图片描述

二、程序计数器

1、介绍

  • 程序计数器(Program Counter Register)也叫PC寄存器,每个线程会通过程序计数器记录当前要执行的字节码指令的地址。
    在这里插入图片描述
  • 在加载阶段,虚拟机将字节码文件中的指令读取到内存之后,会将源文件中的偏移量转换成内存地址。每一条字节码指令都会拥有一个内存地址。
    在这里插入图片描述
  • 在代码执行的过程中,程序计数器会记录下一行字节码指令地址。执行完当前指令之后,虚拟机的执行引擎根据程序计数器执行下一行指令。
  • 程序计数器可以控制程序指令的进行,实现分支、跳转、异常等逻辑。
  • 在多线程执行情况下,Java虚拟机需要通过程序计数器记录CPU切换前解释执行到那一句指令并继续解释运行。

2、程序计数器在运行中会出现内存溢出吗?

  • 内存溢出指的是程序在使用某一块内存区域时,存放的数据需要占用的内存大小超过了虚拟机能提供的内存上限。
  • 因为每个线程只会存储一个固定长度的内存地址,程序计数器是不会发生内存溢出的。
  • 程序员无需对程序计数器做任何处理。

三、栈

1、介绍

  • Java虚拟机栈(Java Virtual Machine Stack)采用栈的数据结构来管理方法调用中的基本数据,先进后出(First In Last Out),每一个方法的调用使用一个栈帧(Stack Frame)来保存。
  • Java虚拟机栈随着线程的创建而创建,而回收则会在线程的销毁时进行。由于方法可能会在不同的线程中执行,每个线程都会包含一个自己的虚拟机栈。

2、栈帧的组成部分

(1)局部变量表

局部变量表的作用是运行过程中存放所有的局部变量。

  • 局部变量表的作用是在方法执行过程中存放所有的局部变量。编译成字节码文件时就可以确定局部变量表的内容。
    在这里插入图片描述
  • 栈帧中的局部变量表是一个数组,数组中每一个位置称之为槽(slot),long和double类型占用两个槽,其他类型占用一个槽。

(2)操作数栈

操作数栈是栈帧中虚拟机在执行指令过程中用来存放临时数据的一块区域。

  • 操作数栈是栈帧中虚拟机在执行指令过程中用来存放中间数据的一块区域。他是一种栈式的数据结构,如果一条指令将一个值压入操作数栈,则后面的指令可以弹出并使用该值。
  • 在编译期就可以确定操作数栈的最大深度,从而在执行时正确的分配内存大小。

(3)帧数据

帧数据主要包含动态链接、方法出口、异常表的引用。

  • 当前类的字节码指令引用了其他类型的属性或方法时,需要将符号引用(编号)转换成对应的运行时常量池中的内存地址。动态链接就保存了编号到运行时常量池的内存地址的映射关系。
    在这里插入图片描述
  • 方法出口指的是方法在正确或者异常结束时,当前栈帧会被弹出,同时程序计数器应该指向上一个栈帧中的下一条指令的地址。所以在当前栈帧中,需要存储此方法出口的地址。
  • 异常表存放的是代码中异常的处理信息,包含了异常捕获的生效范围以及异常发生后跳转到的字节码指令位置。
    在这里插入图片描述

(3)栈内存溢出

  • Java虚拟机栈如果栈帧过多,占用内存超过栈内存可以分配的最大大小就会出现内存溢出。
  • Java虚拟机栈内存溢出时会出现StackOverflowError的错误。

(4)栈的默认大小

如果不指定栈的大小,JVM将创建一个具有默认大小的栈。大小取决于操作系统和计算机的体系结构。
在这里插入图片描述

设置大小

  • 要修改Java虚拟机栈的大小,可以使用虚拟机参数 -Xss。
  • 语法:-Xss栈大小。
  • 单位:字节(默认,必须是1024的倍数)、k或者K(KB)、m或者M(MB)、g或者G(GB)。
  • 与-Xss类似,也可以使用-XX:ThreadStackSize调整标志来配置堆栈大小。格式为:-XX:ThreadStackSize=1024。
  • Java服务端程序开发时,建议将-Xmx和-Xms设置为相同的值,这样程序在启动之后使用的总内存就是最大内存,而无需向java虚拟机再次申请,减少了申请并分配内存时间上的开销,同时也不会出现内存过剩之后堆收缩的情况。
  • -Xmx具体设置的值与实际的应用程序运行环境有关。

HotSpot JVM对栈大小的最大值和最小值有要求

  • Windows(64位)下的JDK8测试最小值为180k,最大值为1024m。
  • 局部变量过多、操作数栈深度过大也会影响栈内存的大小。

3、本地方法栈

  • Java虚拟机栈存储了Java方法调用时的栈帧,而本地方法栈存储的时native本地方法栈帧。
  • 在Hotspot虚拟机中,Java虚拟机栈和本地方法栈实现上使用了同一个栈空间。本地方法栈会在栈内存上生成一个栈帧,临时保存方法的参数同时方便出现异常时也把本地方法的栈信息打印出来。
    在这里插入图片描述
    在这里插入图片描述

四、堆内存

1、介绍

  • 一般Java程序中堆内存时空间最大的一块内存区域。创建出来的对象都存在于堆上。
  • 栈上的局部变量表中,可以存放堆上对象的引用。静态变量也可以存放堆对象的引用,通过静态变量就可以实现对象在线程之间的共享。
    在这里插入图片描述
  • 堆空间有三个需要关注的值,used、total、max。
  • used值的是当前已使用的对内存,total是java虚拟机已经分配的可用堆内存,max是java虚拟机可以分配的最大对内存。

arhas中堆内存相关的功能

  • 堆内存used、total、max三个值可以通过dashboard命令看到
  • 手动指定刷新频率(不指定默认5秒一次):dashboard -i 刷新频率(毫秒)。
    在这里插入图片描述
  • 如果不设置任何的虚拟机参数,max默认时系统内存的1/4、total默认是系统内存的1/64。在实际应用中一般都需要设置total和max的值。

2、是不是当used=total=max的时候,堆内存就溢出了?

  • 不是,堆内存溢出的判断条件比较复杂。

3、堆大小

  • 要修改堆的大小,可以使用虚拟机参数-Xmx(max最大值)和-Xms(初始的total)。
  • 语法:-Xmx值 -Xms值
  • 单位:字节(默认,必须是1024的倍数)、k或者K(KB)、m或者M(MB)、g或者G(GB)。
  • 限制:Xmx必须大于2MB,Xms必须大于1MB。

为什么arthas中显示的heap堆大小与设置的值不一样

  • arthas中的heap堆内存使用了JMX技术中内存获取方式,这种方式与垃圾回收器有关,计算的是可以分配对象的内存,而不是整个内存。
    在这里插入图片描述

五、方法区

1、介绍

方法区是存放基础信息的位置,线程共享,主要包含三个部分内容:

  • 类的元信息:保存了所有类的基本信息。一般称之为InstanceKlass对象。在类加载阶段完成。
    d

  • 运行时常量池: 保存了字节码文件中的常量池内容。

  • 字符串常量池:保存了字符串常量。
    在这里插入图片描述

方法区是《Java虚拟机规范》中设计的虚拟概念,每款Java虚拟机在实现上都各不相同。Hotspot设计如下:

  • JDK7及之前的版本将方法区存放在堆区域中的永久代空间,堆的大小由虚拟机参数来控制。堆的大小由虚拟机参数-XX:MaxPermSize=值来控制。
  • JDK8及之后的版本将方法区存放在元空间中,元空间位于操作系统维护的直接内存中,默认情况下只要不超过操作系统承受的上限,可以一直分配。可以使用-XX:MaxMetaspaceSize=值将元空间最大大小进行限制。
    在这里插入图片描述

2、ByteBuddy框架的基本使用方法

ByteBuddy是一个基于Java的开源库,用于生成和操作Java字节码。

  • 引入依赖
    在这里插入图片描述
  • 创建ClassWriter对象
    在这里插入图片描述
  • 调用visit方法,创建字节码数据
    在这里插入图片描述
    在这里插入图片描述

3、字符串常量池

intern

  • JDK6版本中intern方法会把第一次遇到的字符串实例复制到永久代的字符串常量池中,返回的也是永久代里面这个字符串实例的引用。JVM启动时就会把java加入到常量池中。
    在这里插入图片描述

  • JDK7及之后版本中由于字符串常量池也在堆上,所以intern()方法会把第一次遇到的字符串的引用放入字符串常量池中。
    在这里插入图片描述

六、直接内存

1、介绍

直接内存(Direct Memory)并不在《Java虚拟机规范》中存在,所以并不属于Java运行时的内存区域。

  • 在JDK1.4中引入了NIO机制,使用了直接内存,主要是为了解决一下两个问题:
    • Java堆中的对象如果不在使用要回收,回收时会影响对象的创建和使用。
    • IO操作比如读文件,需要先把文件读入直接内存(缓冲区)再把数据复制到Java堆中。现在直接放入直接内存即可,同时java堆上维护直接内存的引用,减少了数据复制的开销。写文件也是类似的思路。
      在这里插入图片描述

2、直接内存中创建数据

  • 要创建直接内存上的数据,可以使用ByteBuffer。
  • 语法:ByteBuffer directBuffer = ByteBuffer.allocateDirect(size);
  • 注意事项:arthas的memory命令可以查看直接内存大小,属性名direct。
    在这里插入图片描述

3、设置大小

如果需要手动设置直接内存的大小,可以使用-XX:MaxDirectMemorySize=大小

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

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

相关文章

js中使用原型链增加方法后,遍历对象的key-value时会遍历出方法

原因:js使用原型链实现方法时,这个方法默认是可迭代的,所以在遍历时就会被遍历出来, 例: Array.prototype.remove function(n){return this.slice(0,n).concat(this.slice(n1,this.length));}var cc ["cccaaaa…

【算法】Splay详解

Splay 引入 Splay旋转操作splay操作插入操作查询x排名查询排名为x删除操作查询前驱/后继模板Splay时间复杂度分析 进阶操作截取区间区间加,区间赋值,区间查询,区间最值区间翻转原序列整体插入指定位置插入整体插入末尾区间最大子段和 一些好题…

【windows|014】TCP协议详解

🍁博主简介: 🏅云计算领域优质创作者 🏅2022年CSDN新星计划python赛道第一名 🏅2022年CSDN原力计划优质作者 ​ 🏅阿里云ACE认证高级工程师 ​ 🏅阿里云开发者社区专家博主 💊交流社…

LLM用于时序预测真的不行,连推理能力都没用到

语言模型真的能用于时序预测吗?根据贝特里奇头条定律(任何以问号结尾的新闻标题,都能够用「不」来回答),答案应该是否定的。事实似乎也果然如此:强大如斯的 LLM 并不能很好地处理时序数据。 时序&#xff0…

Prometheus监控主机进程

前言 客户端安装及配置 Premetheus服务端配置 模板导入 grafana效果图 前言 此场景主要是利用process-export监控主机的进程存活、资源占用率,防止进程挂掉导致服务崩溃 gitlab地址:GitHub - ncabatoff/process-exporter: Prometheus exporter that…

开发体育直播平台:高并发问题解决手段及架构设计思路

在追求极致观赛体验的体育直播领域,高并发处理能力成为了衡量系统性能与稳定性的关键标尺。东莞梦幻网络科技技术团队,凭借其在互联网领域的深厚积累与前瞻视野,成功打造了一套高效、稳定的体育赛事直播系统,有效解决了高并发带来…

【Python】sklearn教程

1. sklearn库介绍 sklearn是 Python 中一个非常重要的机器学习库,全称为scikit-learn。它是基于Python语言的机器学习工具,提供了一系列简单高效的机器学习算法。sklearn库通常与NumPy和SciPy库一起使用,用于数据预处理、特征选择、模型训练…

Centos 使用nfs配置共享目录使docker集群所有容器日志统一主机访问

Centos 使用nfs配置共享目录,使docker集群所有容器日志统一存放在主机一个共享目录下,供开发人员访问查看 准备两台或以上Centos服务器 192.168.0.1 nfs服务器 192.168.0.2 nfs客户端 以root用户登录192.168.0.1服务器,执行以下操作 注意先…

【JavaScript】解决 JavaScript 语言报错:Uncaught SyntaxError: Unexpected identifier

文章目录 一、背景介绍常见场景 二、报错信息解析三、常见原因分析1. 缺少必要的标点符号2. 使用了不正确的标识符3. 关键词拼写错误4. 变量名与保留字冲突 四、解决方案与预防措施1. 检查和添加必要的标点符号2. 使用正确的标识符3. 检查关键词拼写4. 避免使用保留字作为变量名…

ReentrantLock的源码实现和原理介绍

目录 一、概述 二、ReentrantLock的整体结构 三、ReentrantLock 和Synchronized相比 四、ReentrantLock 公平锁和非公平锁实现 4.1 ReentrantLock 源码解读 4.1.1 ReentrantLock 类源码解读 4.1.1.1 Lock接口 4.1.1.2 Sync抽象类 4.1.1.3 NonfairSync()和FairSync() 4…

《0基础》学习Python——第十讲

小知识点补充 一、json大字符串 JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,它以易于阅读和编写的方式为基础,同时也易于解析和生成。因为其简洁性和可读性,JSON已成为数据交换的首选格式。 大字符…

超大模型加载转换Trick

在深度学习领域,大模型的训练和推理通常需要消耗大量的计算和内存。如何高效地加载和使用大模型是一个相当关键的问题。在这篇博客中,我将分享一些关于更快加载大模型和减少内存的技巧。 1.问题分析 假设现在我们有一个236B 超大模型的原始权重的 check…

jmeter-beanshell学习9-放弃beanshell

写这篇时候道心不稳了,前面写了好几篇benashell元件,突然发现应该放弃。想回去改前面的文章,看了看无从下手,反正已经这样了,我淋了雨,那就希望别人也没有伞吧,哈哈哈哈,放在第九篇送…

DHCP原理及配置

目录 一、DHCP原理 DHCP介绍 DHCP工作原理 DHCP分配方式 工作原理 DHCP重新登录 DHCP优点 二、DHCP配置 一、DHCP原理 1 DHCP介绍 大家都知道,现在出门很多地方基本上都有WIFI,那么有没有想过这样一个问题,平时在家里都是“固定”的…

互联网十万个为什么之什么是专有网络VPC?

专有网络VPC有什么优势? 专有网络VPC具有安全可靠、灵活可控、简单易用的特性和较强的可扩展性。 安全可靠 每个VPC都有一个独立的隧道号,一个隧道号对应着一个虚拟化网络。VPC之间通过隧道号进行隔离: 由于VPC内部存在交换机和路由器&#…

PyTorch人脸识别

新书速览|PyTorch深度学习与企业级项目实战-CSDN博客 一套基本的人脸识别系统主要包含三部分:检测器、识别器和分类器,流程架构如图11-3所示: 图11-5 检测器负责检测图片中的人脸,再将检测出来的人脸感兴趣区域(Reg…

如何在单片机外部Flash存储器上部署高效文件系统:从原理到实现

目录 1.Littlefs文件系统 1.1文件系统简介 2 Littlefs文件系统移植到单片机上 2.1 添加源代码 2.2 编辑接口函数 2.3 测试代码 1.Littlefs文件系统 1.1文件系统简介 littlefs文件系统源码下载地址:littlefs-project/littlefs: A little fail-safe filesystem…

Unity Shader学习笔记

Shader类型 类型详情Standard Surface Shader标准表面着色器,基于物理的着色系统,用于模拟各种材质效果,如石头、木材、玻璃、塑料和金属等。Unlit Shader最简单的着色器,不包含光照但包含雾效,只由最基础的Vertex Sh…

Pytorch使用Dataset加载数据

1、前言: 在阅读之前,需要配置好对应pytorch版本。 对于一般学习,使用cpu版本的即可。参考教程点我 导入pytorch包,使用如下命令即可。 import torch # 注意虽然叫pytorch,但是在引用时是引用torch2、神经网络获取…

【C++】—— 初识C++

【C】—— 初识C 一、什么是 C二、C 的发展历史三、C 版本更新四、C 的重要性五、C 在工作领域中的运用六、C 书籍推荐: 一、什么是 C C语言 是结构化和模块化的语言,适合处理较小规模的程序。对于复杂的问题,规模较大的程序,需要…