当前位置: 首页 > ds >正文

JVM之【运行时数据区】

目录

前言

线程私有区域

程序计数器

虚拟机栈

概述

特点

存在的异常

本地方法栈

线程共享区域

堆空间

概述

内存划分

JDK7及以前

JDK8

JDK9

本地内存

元空间

直接内存

相关的JVM参数


前言

JVM运行Java程序时,会把自己管理的内存分为多个不同的数据区域,这些区域分为线程私有的内存区域和线程共享的内存区域

线程私有区域

创建每条线程,JVM都会为线程分配的独立的区域,这些区域的生命周期和线程一致,这些区域对其他线程是不可见的,只有当前线程可以访问;线程私有的内存区域有程序计数器、虚拟机栈、本地方法栈

程序计数器

是JVM所有内存区域中,唯一不会发生内存溢出的区域,核心作用如下

  • 记录线程正在执行的字节码指令地址,执行引擎处理完某条指令后,程序计数器需要更新将指针指向下一条要执行的指令地址,执行引擎会根据程序计数器记录的地址来执行对应的指令
  • 保证线程发生CPU时间片切换后能恢复到正确的位置执行

虚拟机栈

概述

又叫Java栈,主要作用是负责程序如何执行,如何处理数据;当线程执行一个方法时,会为方法生成一个栈帧,方法的调用对应着虚拟机栈中一个栈帧的入栈到出栈的过程;栈帧主要包含局部变量表、操作数栈、动态链接、方法出口等;执行引擎只会执行位于栈顶的栈帧,也就是当前方法

特点

  • 操作数栈的栈顶数据会放到高速缓存或者寄存器中,访问速度快
  • 虚拟机栈区域中不存在垃圾收集,但是存在内存溢出
  • 每条线程的虚拟机栈默认大小为1M

存在的异常

  • StackOverflowError:线程请求的栈深度过深,大于虚拟机所允许的最大深度
  • OutOfMemoryError:扩容时无法获取到足够的内存空间

本地方法栈

用于执行由C语言编写的本地方法,本地方法的执行是在操作系统中执行的,并不是在JVM中执行,所以使用的是操作系统的程序计数器而不是JVM的程序计数器,可以访问JVM的任何内存区域,也可以直接使用CPU的寄存器和本地内存

线程共享区域

Java程序在运行时,这些区域是程序中所有的线程都可见的,创建后会和JVM的生命周期一致,线程共享的内存区域有堆空间、本地内存

堆空间

概述

Java堆是用来存储数据的,主要解决的是数据的存放问题;堆空间是JVM启动时创建出来的内存区域,默认情况下不通过参数设置堆的大小的话,堆空间的起始大小为当前物理机内存的1/64,最大大小为当前物理机内存的1/4;在程序执行过程中,产生的大部分实例对象都会被放到堆空间存储

内存划分

Java堆空间的内存划分变化的比较频繁,不同的Java版本中,堆空间的内存划分会发生变化,从本质上来讲影响内存结构变化的原因是JVM运行时使用的垃圾收集器

JDK7及以前

堆空间被划分为三个区域:新生代、老年代、永久代

  • 新生代:eden区+s0区+s1区,理论比例8:1:1(实际6:1:1,JVM有自适应调节机制)
  • 老年代:old区,和新生代的比例为2:1,存储年龄达标的对象和大对象(超过设定的阈值大小)
  • 永久代:方法区,存储类的元数据信息
JDK8

将永久代整合成元数据空间,并放到堆空间之外的本地内存中

  • 新生代
  • 老年代
JDK9

默认垃圾收集器由原来的分代变成G1,有了分区的概念并保留了新生代和老年代的概念,G1将堆空间划分为若干大小相等的Region区,体现了逻辑分代物理分区的思想

  • 代表eden的Region区
  • 代表survivor的Region区
  • 代表old的Region区
  • 代表humongous的Region区,存放大对象(G1中不会让大对象进入老年代),判断大对象的方式是对象大小超过了Region区大小的一半

本地内存

主要可分为两部分:元空间和直接内存

元空间

主要用于存放运行时常量池和类信息

  • 运行时常量池:final常量值、基本类型数值、符号引用
  • 类信息:属性、方法、类元信息(通过反射能获取到的元数据信息)

直接内存

不是虚拟机的内存区域,在创建时直接向操作系统申请内存,直接使用物理内存,和堆空间相比,访问直接内存中的数据速度更快

相关的JVM参数

  1. [-Xss]:设置虚拟机栈的大小
  2. [-XX:NewRatio]:指定新生代所占比例
  3. [-Xmn]:强制指定新生代的内存最大大小
  4. [-XX:SurvivorRatio]:设置eden区和survivor区的比例
  5. [-XX:+UseAdaptiveSizePolicy]:开启JVM自适应机制(默认开启)
  6. [-Xms]:指定堆的初始内存大小
  7. [-Xmx]:指定堆的最大内存大小
  8. [-XX:G1HeapRegionSize]:垃圾收集器使用的是G1,指定每个Region区的大小,不推荐手动设置,使用默认即可
  9. [-XX:G1NewSizePercent]:垃圾收集器使用的是G1,设置新生代初始占比,默认占堆内存的5%
  10. [-XX:G1MaxNewSizePercent]:垃圾收集器使用的是G1,设置新生代最大占比,建议最多不超过60%
  11. [-XX:MaxDirectMemorySize]:设置直接内存的最大内存大小
http://www.xdnf.cn/news/19017.html

相关文章:

  • Nginx访问限制学习笔记
  • 论文学习日志——忆阻器与神经网络——part1
  • 基于XiaothinkT6语言模型的文本相似度计算:轻量方案实现文本匹配与去重
  • AT_abc403_f [ABC403F] Shortest One Formula
  • 阿里云docker搭建的mysql无法访问
  • Docker化性能监控平台搭建:JMeter+InfluxDB+Grafana全攻略
  • GRPO算法:告别PPO内存炸弹,无需价值函数,用组内排名代替绝对评分
  • NUMA架构
  • Java大厂面试全解析:从Spring Boot到微服务架构实战
  • 矩阵初等变换的几何含义
  • 【LeetCode】动态规划——542.01 矩阵
  • 系统设计(数据库/微服务)
  • 计算机网络的发展演进历程
  • 2 梯度下降算法
  • 英伟达 Spectrum-XGS:重构 AI 基础设施,开启跨域超级工厂时代
  • 氯化钕:以稀土之力引领科技创新
  • Spring AI 入门指南:三步将AI集成到Spring Boot应用
  • Java大厂面试实战:从Spring Boot到微服务架构的全链路技术剖析
  • MySQL 面试题系列(四)
  • Mysql——日志
  • 力扣hot100:搜索旋转排序数组和寻找旋转排序数组中的最小值(33,153)
  • TikTok广告投放革命:指纹云手机如何实现智能群控与降本增效
  • Mac中修改Word的Normal.dotm文件
  • CSS实现内凹圆角边框技巧(高频)
  • 绿算技术解密金融科技安全:高性能计算与存储驱动金融防火墙新时代
  • 【拥抱AI】一起学卷积神经网络(CNN)
  • 一天推荐一款实用的手柄零件————线性霍尔
  • Zynq开发实践(FPGA之verilog仿真)
  • Flask 之上下文详解:从原理到实战
  • OSG+Qt —— 笔记3- Qt窗口绘制模型的三条轴(附源码)