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

深入理解JAVA虚拟机(一)

介绍JAVA虚拟机的运行时数据区域

按照物理结构来划分:java虚拟机主要由以下几部分构成栈、堆和程序计数器,其中栈又可以分为虚拟机栈VM stack 和 本地方法栈 Native Method Statck,堆可以划分方法区和普通的堆内存。按照逻辑划分线程私有空间和线程共线空间。

虚拟机栈、本地方法栈、程序计数器都是属于线程私有的,生命周期随着线程的创建和销毁。

方法区、堆内存属于线程共线空间,后续主要是通过垃圾回收机制来管理内存的。

(1)Java虚拟机栈

线程私有的,用于存储局部变量表、操作数栈、动态链接、方法出口,其中局部变量表存放的是基本数据类型和引用数据类型的Reference。一个槽占32bit,基本类型占用一个槽位,long和double占用两个槽位。

     注意:数组变量也是存储在虚拟机占里面的,如果开辟的数组变量内存过大,可能会引起StackOverFlowError。

导致虚拟机栈溢出的情况如下:

  • 检查递归方法,确保有终止条件并且在合理的时间内结束递归。
  • 减少方法内部的局部变量数量,特别是大的数组或集合,可以考虑使用全局静态变量。
  • 增加虚拟机栈的大小。可以通过JVM启动参数-Xss来调整,例如-Xsslm将栈大小设置为1M。
  • 单个线程请求栈深度太深导致的,可以尝试将算法改为迭代形式,减少栈的使用。

(2)程序计数器

意义上就是一个程序控制流的指示器,主要用于在线程轮流切换的时候,能够恢复到正确的执行位置,每个线程都有自己独立的程序计数器,各条线程之间计数器互不影响,独立存储。

(3)本地方法栈

和虚拟机栈作用一样,区别虚拟机栈服务于Java方法,本地方法栈则是服务于本地(Native)方法。

(4)Java堆

虚拟机所管理的内存中最大的一块,也是GC主要回收的管理内存的部分。“GC”采用粉带收集理论设计的,把Java堆划分不同的年龄段“新生代”、“老年代”。“永久代”、其中新生代有划分为“Eden空间”、“From Survivor空间”、“To Survivor空间”。

(5)方法区

主要解析Class文件之后,存放类型信息、常量、静态变量、字段、方法、接口。其中运行时常量池(Runtime Constant Pool)也是方法区的一部分,主要用于存放编译期生成的各种字面量与符号引用。

(6)直接内存

NIO(New Input/Output)类,引入了一种基于通道(channel)于缓冲器(Buffer)的I/O方式,它可以使用Navtive函数库直接分配堆外内存。

http://www.lryc.cn/news/469492.html

相关文章:

  • 从Excel文件中读取数据
  • 深入剖析MySQL的索引机制及其选型
  • 校园表白墙源码修复版
  • Android 内存优化——常见内存泄露及优化方案
  • Qt6.7.2中使用OpenSSL的坑
  • Mybatis-08.基础操作-删除
  • 通过FDM升级Firepower
  • 使用 Kibana 将地理空间数据导入 Elasticsearch 以供 ES|QL 使用
  • demo说明
  • 【c++篇】:从基础到实践--c++内存管理技巧与模版编程基础
  • 如何减小 Maven 项目生成的 JAR 包体积 提升运维效率
  • Python自动化会议记录与摘要生成
  • SwiftUI 中 List 或 Form 子视图关联的 swipeAction 导致展开动画异常的解决
  • Apache Paimon Catalog
  • C++基础:三个字符串也能搞大小?
  • 了解AIGC——自然语言处理与生成
  • Modern CMake 简明教程(8)- 集成Qt
  • 人脸应用实例:性别年龄预测
  • 学习threejs,通过THREE.Raycaster给模型绑定点击事件
  • Jackson Json序列化反序列化的两个坑
  • k8s_Pod健康检查
  • 基于DDPG算法的股票量化交易
  • eIQ笔记(UI介绍+Loss曲线+OpenART例程)
  • 微信小程序——消息订阅
  • 网络原理(传输层)->TCP协议解
  • oracle imp和exp 导入不同库的用户和表空间
  • 滚珠丝杆的精度级别如何分?
  • ComfyUI初体验
  • DPI-C动态库so的使用
  • Java避坑案例 - 高并发场景下的分布式缓存策略