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

深入理解JVM

文章目录

  • JVM
    • 区域划分(运行时数据区域)
    • 对象的组成
    • 垃圾收集
    • 类加载

JVM

区域划分(运行时数据区域)

  • 线程独有的
  1. 程序计数器——指向下一行要执行的代码行号——唯一一个没有规定OOM的地方
  2. 栈:本地方法栈、虚拟机栈
  • 线程共享的
  1. 方法区
  2. 堆——存对象的地方,“几乎”所有的对象实例都在这里分配内存

对象的组成

  • 分配内存给对象的方式
  1. 假如内存是规整的——指针碰撞——要整理
    指针移动需要多大的空间,给线程分配多大的空间,问题是要整理,把用过的不再需要的整理起来
  2. 假如不是规整的——空闲列表——空闲碎片
    会产生大量的空间碎片问题
  3. 解决 一种是CAS(乐观锁) 一种是TLAB(本地线程分配缓冲) TLAB是线程私有的小块内存区域 作用就是减少多线程环境下对象分配时的锁竞争
  • 对象的内存布局
  1. 对象头
    (1)Mark Word:存储对象自身的运行时数据,如哈希码(HashCode)、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳等
    (2)指向对象类型的指针
    (3)如果是数组的话 还额外存储了数组长度
  2. 实例数据
    对象真正存储的有效信息
  3. 对齐填充
    对象起始地址必须是8字节的整数倍,没有对齐的就需要通过对齐填充来补全
  • 对象的访问方式
  1. 直接指针
  2. 句柄

垃圾收集

  • 哪些是垃圾
  1. 先判生死
    (1)脑门刻字法——引用计数法
    两个对象互相引用着对方,导致它们的引用计数都不为零,引用计数算法也
    就无法回收它们。
    (2)平地长树法——可达性分析
    通过一系列称为“GC Roots”的根对象作为起始节点集,从这些节点开始,根据引用关系向下搜索,搜索过程所走过的路径称为“引用链”,如果某个对象到GC Roots间没有任何引用链相连,则证明此对象是不可能再被使用的。
    在Java技术体系里面,固定可作为GC Roots的对象包括以下几种:
    • 在虚拟机栈(栈帧中的本地变量表)中引用的对象,譬如各个线程被调用的方法堆栈中使用到的参数、局部变量、临时变量等。
    • 在方法区中类静态属性引用的对象,譬如Java类的引用类型静态变量。
    • 在方法区中常量引用的对象,譬如字符串常量池(String Table)里的引用。
    • 在本地方法栈中JNI(即通常所说的Native方法)引用的对象。
    • Java虚拟机内部的引用,如基本数据类型对应的Class对象,一些常驻的异常对象(比如NullPointExcepiton、OutOfMemoryError)等,还有系统类加载器。
    • 所有被同步锁(synchronized关键字)持有的对象。
    • 反映Java虚拟机内部情况的JMXBean、JVMTI中注册的回调、本地代码缓存等。
  2. 再谈引用
  • 什么时间回收
    1. 分代收集理论
    • 强分代假说——活的越久的,就越倾向于活下去
    • 弱分代假说——绝大多数对象都是朝生熄灭的
    • 跨代引用假说——仅占极少数
    1. 收集算法
    • 标记-清除
      • 简单
      • 空间碎片问题
      • stop the world
    • 标记-复制
      • 没有空间碎片
      • 仅适用于收集效率高的场景
      • 只有一半的有效空间
    • 标记-整理
  • 怎么样回收
  • 并发的可达性分析
    当且仅当以下两个条件同时满足时,会产生“对象消失”的问题,即原本应该是黑色的对象被误标为白色:
    • 赋值器插入了一条或多条从黑色对象到白色对象的新引用;
    • 赋值器删除了全部从灰色对象到该白色对象的直接或间接引用。
  1. 增量更新——破坏第一个条件(CMS)
    黑色对象一旦新插入了指向白色对象的引用之后,它就变回灰色对象了
  2. 原始快照——破坏第二个条件(G1)
    无论引用关系删除与否,都会按照刚刚开始扫描那一刻的对象图快照来
    进行搜索
  • 经典的垃圾收集器
  1. CMS
    • 处理器资源比较敏感
    • 无法处理浮动垃圾
    • 大量空间碎片
  2. G1
    • 无内存碎片
    • 负载比较高
  • 内存分配与回收策略
  1. 对象优先在Eden
  2. 大对象直接进老年代
  3. 长期存活的进入到老年代
  4. 动态年龄判定
  5. 空间分配担保

类加载

  • 类的加载过程
  1. 加载
    • 通过一个类的全限定名来获取定义此类的二进制字节流。
    • 将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构。
    • 在内存中生成一个代表这个类的java.lang.Class对象,作为方法区这个类的各种数据的访问入口。
  2. 验证
    确保Class文件的字节流中包含的信息符合《Java虚拟机规范》的全部约束要求
    • 文件格式验证
    • 元数据验证
    • 字节码验证
    • 符号引用验证
  3. 准备
    正式为类中定义的变量(即静态变量,被static修饰的变量)分配内存并设置类变量初始值的阶段
  4. 解析
    Java虚拟机将常量池内的符号引用替换为直接引用的过程
    • 类或接口的解析
    • 字段解析
    • 方法解析
    • 接口方法解析
  5. 初始化
    类加载过程的最后一个步骤,Java虚拟机真正开始执行类中编写的Java程序代码,将主导权移交给应用程序。
  • 类加载器
  1. 双亲委派模型
    • 启动类加载器
      • 固定路径下的,固定jar包的
    • 扩展类加载器
      • 对Java语言的扩展
    • 应用程序类加载器(系统类加载器)
      • 我们写的程序
  2. 破坏双亲委派模型
http://www.dtcms.com/a/274859.html

相关文章:

  • 视频翻译用什么软件?这里有5个高效推荐
  • 编码技术: PRBS, 8B/10B
  • MCU芯片内部的ECC安全机制
  • 提升你的AI交互技能:使用Anthropic互动提示教程
  • c语言中的数组IV
  • Qt:布局管理器Layout
  • flutter鸿蒙版 环境配置
  • Deekseek 学习笔记
  • 北京-4年功能测试2年空窗-报培训班学测开-第四十八天
  • 信创 CDC 实战 | TiDB 实时入仓难点与解决方案解析(以 ClickHouse 为例)
  • 【面板数据】省级泰尔指数及城乡收入差距测算(1990-2024年)
  • 大模型人类反馈强化学习RLHF 凭什么火出圈?人类反馈 + 强化学习,解锁 AI 行为可控密码
  • 盛世美颜伴杭州--花皙蔻牡丹盛世美颜精华油获选“2025杭州特色伴手礼”
  • 【Quest开发】快速添加可手指触摸按钮
  • unity VR linerenderer的线会被UI盖住
  • 微算法科技基于格密码的量子加密技术,融入LSQb算法的信息隐藏与传输过程中,实现抗量子攻击策略强化
  • 20250710-2-Kubernetes 集群部署、配置和验证-网络组件存在的意义?_笔记
  • 车载诊断进阶篇 --- 关于网关转发性能引起的思考
  • JAVA入门——安装java环境
  • 智能运维管理平台:AI赋能的数字化转型引擎
  • 从大模型到云游戏,国鑫SY8108G-G4如何化身“全能AI引擎”?
  • 挥别Feign,拥抱Spring 6.1 RestClient:高可用HTTP客户端构建之路
  • 雷达遥感星座微波射频组件抗辐照MCU的选型与实践
  • HarmonyOS基础概念
  • windows 装了 python2 和 python3 如何切换默认版本
  • 1.1.2 运算符与表达式——AI教你学Django
  • 常见的数集 N,Z,R,Q,C
  • osgb转fbx,osgb转su,osgb转obj,osgb转3dmax,osgb转glb,osgb转gltf,osgb转通用格式osgb转SKP
  • Kubernetes服务暴露与负载均衡深度探析
  • SQL:数据库查询语言的核心技术