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

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.dtcms.com/a/352672.html

相关文章:

  • 深度学习-----ptorch框架认识-手写数字识别.py项目解读
  • 2025年渗透测试面试题总结-34(题目+回答)
  • three.js+WebGL踩坑经验合集(9.2):polygonOffsetFactor工作原理大揭秘
  • Langchian-chatchat私有化部署和踩坑问题以及解决方案[v0.3.1]
  • More Effective C++ 条款10:在构造函数中防止资源泄漏
  • 二维费用背包 分组背包
  • 小范围疫情防控元胞自动机模拟matlab
  • 深入剖析容器文件系统:原理、实现与资源占用分析
  • 游戏空间划分技术
  • 家庭财务规划与投资系统的设计与实现(代码+数据库+LW)
  • 声网RTC稳定连麦、超分清晰,出海直播技术不再难选
  • AT_abc403_f [ABC403F] Shortest One Formula
  • 【44页PPT】极简架构MES系统解决方案介绍(附下载方式)
  • 【Python】雷达簇类ply点云仿真生成,以及聚类算法的簇类目标检测
  • flutter专栏--dart基础知识
  • WebGIS开发智慧校园(6)JavaScript
  • 破解VMware迁移难题的技术
  • SSH密钥登录全流程详解
  • LeetCode-221. 最大正方形
  • 多模块 Starter 最佳实践(强烈推荐!!!)
  • Quarkus OIDC 安全链路时序图
  • git换行行为差异简述;.editorconfig换行行为简述
  • 打工人日报#20250826
  • 【PS实战】制作hello标志设计:从选区到色彩填充的流程(大学作业)
  • springboot启动的时候,只打印logo,不打印其他的任何日志的原因
  • 【ElasticSearch】数据同步
  • 人形机器人的“奥运会“:宇树科技领跑,动捕技术成训练关键
  • git submodule的基本使用
  • 数据与端点安全 (Protect data and apps)
  • 利用 Python 爬虫按关键字搜索 1688 商品详情 API 返回值说明(代码示例)实战指南