JVM内存

简介: JVM内存

JVM学习(👀️ 深入理解Java虚拟机)

  • JVM内存管理脑图
  • JVM是什么?
  • JVM(Java Virtual Machine 简称JVM),是Java的核心所在。也是Java语言与平台无关性的基础
  • 参考软件架构风格中虚拟机风格中的解释器风格
  • JVM种类
  • Sun Classic(始祖)
  • HotSpot(运用最广)
  • 等其他虚拟机

第一节:JVM的内存结构

如图:

JDK- 6结构(CV大法)

  • 如图:

JDK- 8结构(CV大法)

  • 如图:
  • 是否由所有线程共有?
  • 线程共享
  • 方法区、堆、执行引擎、本地库接口
  • 非线程共享
  • 虚拟机栈、本地方法栈、程序计数器
  • 各数据区域的作用
  • 程序计数器(私有):当前线程所执行的字节码的行号指示器,这是唯一一个不会发生OOM的区域
  • 虚拟机栈(私有):保存了方法执行时的栈帧;栈帧描述了方法执行时的局部变量表操作数栈动态连接、**方法出口 **等信息
  • 局部变量表:描述了编译期可知的基本数据类型(如,byte、char......)
  • 本地方法栈(私有):与虚拟机栈类似,但是本地方法栈为Native(本地)方法服务;而虚拟机栈为Java方法服务
  • 堆(共享):大部分的Java实例对象都在堆里面,也是GC的管理区域
  • 方法区(共享):存放着类型信息、常量、静态变量等数据
  • JDK- 8放弃永久代,改用元空间
  • 运行时常量池属于方法区,运行时常量池用于存放常量池表(编译时生成的各种字面量、符号引用)

第二节:对象

  • 对象由那些部分组成?
  • 对象头
  • 自身的运行时数据
  • 类型指针
  • 实例数据
  • 对象真正存储的有效信息
  • 对齐填充
  • 无实际意义,占位符

第三节:内存回收

程序计数器、虚拟机栈、本地方法栈3个区域随线程而生,随线程而灭,不需要GC

第四节:如何判断对象已经“死亡”

内存的回收的前提是对象已经死亡,也就是说不存在任何的引用,因此如何判断对象已死,这十分重要

  • 传统的判断对象已死的方法有两种
  • 引用计数法
  • 原理:存在引用则加一,减少引用则减一,为0时,说明对象不存在引用(已经死亡)
  • 优势:简单易于实现
  • 缺点:无法解决循环引用
  • 可达性分析法(Java所采用的方法)
  • 原理:如果任何对象可以找到GCRoots根节点,则认为该对象存活否则死亡
  • 卡表:解决跨代引用,JVM做全堆扫描的性能问题
  • 写屏障:维护卡表的状态,防止出现脏读;即便写屏障存在性能损耗,但是依然优于全堆扫描
  • 如图所示:
  • 确定对象死亡的方法?
  • 对象至少需要经历两次标记
  • 第一次标记:对象与GcRoots没有关联
  • 第二次标记:经历一次标记的对象是否有必要执行finalize();这是对象"自救"的最后一步 //TODO:2023/3/21日发布前四章

第五节:垃圾收集算法

分代收集理论

  • 弱分代假说:大部分对象都朝生夕灭
  • 强分代假说:熬过越多次GC的对象,则对象越难以消亡
  • 跨代引用假说:跨代引用相对于同代引用来说,仅占极少数
  • GC种类
  • 新生代收集(Minor GC/Young GC):指目标只是新生代的垃圾收集。
  • 老年代收集(Major GC/Old GC):指目标只是老年代的垃圾收集。
  • 整堆收集(Full GC):收集整个Java堆和方法区的垃圾收集。

分代收集算法

  • 标记-清除算法
  • 首先标记存活\死亡的对象,然后回收被标记\未标记的对象
  • 缺点:内存碎片化严重、执行效率不稳定
  • 如图:
  • 标记-复制算法
  • 为了解决标记-清除算法效率较低
  • 将内存划分为两块,一次只是用其中一块,当一块内存已经使用完时,将存活的对象移动至另一块,在一次性清理使用完成的内存块。
  • 缺点:内存浪费严重
  • 如图:
  • 标记-整理算法
  • 为了解决标记-复制算法当存活对象较多时,复制效率较低;且浪费大量空间
  • 与标记-清除算法类似,但是不需要清除对象;而是将存活的对象移动到内存某一侧,然后清除另一侧的对象
  • 缺点:需要暂停用户线程保证一致性,性能与一致性需要综合考虑
  • 如图:
  • Stop The World:
  • 目的:暂停用户线程;
  • 为何?当GC时,为了保证对象标记、清除的正确性、完整性。需要STW,因为如果不STW,会导致标记错误。
  • 三色标记
  • 白色:不可达
  • 灰色:已经被垃圾收集器扫描,但是还存在未扫描引用
  • 黑色:对象及其引用全部被扫描
  • 如何解决对象消失问题:
  • 增量更新:当存在黑色指向白色的引用时,记住当前黑色对象;在并发扫描之后,重新扫描。( 一旦存在黑引用白,则修改黑为灰)
  • 原始快照:当存在灰色删除白色引用时,记录白色对象;在扫描结束后,以灰色为根,重新扫面。( 不在乎是否真的删除,因为永远都会以开始扫描的对象图来进行搜索)

第六章 垃圾收集器

  • Serial收集器
  • GC线程为单线程
  • 如图:
  • ParNew收集器
  • GC线程多线程
  • 如图:
  • Parallel Scavenge收集器
  • 基于标记-复制算法
  • 与ParNew相似
  • Parallel Scavenge关注的是吞吐量;区别于其它垃圾收集器,它不关注用户线程暂停时间
  • CMS(Concurrent Mark Sweep)收集器
  • 基于标记-清除算法
  • 关注服务的响应时间,希望系统的停顿时间尽量短
  • 采用增量更新解决标记对象消失
  • 包含四步
  • 初始标记(需要STW);标记GcRoots能直接关联的对象
  • 并发标记(不需要STW);从GcRoots直接关联的对象开始遍历对象图
  • 重新标记(需要STW);修正在并发阶段,线程修改的对象标记
  • 并发清除(不需要STW);并发删除对象
  • CMS示意图
  • GarbageFirst(G1)收集器
  • 局部基于标记-复制算法,整体基于标记-整理算法
  • 采用原始快照解决标记对象消失
  • G1收集器区别于其余的收集器,不在于数据的分代(但是依然遵循分代理论);G1将内存分治为多个Region,优先回收收益最高的Region
  • G1运行过程
  • 初始标记:仅标记GcRoots能直接关联的对象(需要STW)
  • 并发标记:从GcRoots开始进行全图的可达性分析
  • 最终标记:修正并发标记阶段被修改的标记(需要STW)
  • 筛选回收:对Region的价值进行评估,复制旧的Region中存活的实例到新的Region,清理旧的Region(需要STW)
  • 如图:
目录
相关文章
|
1月前
|
存储 安全 Java
jvm 锁的 膨胀过程?锁内存怎么变化的
【10月更文挑战第3天】在Java虚拟机(JVM)中,`synchronized`关键字用于实现同步,确保多个线程在访问共享资源时的一致性和线程安全。JVM对`synchronized`进行了优化,以适应不同的竞争场景,这种优化主要体现在锁的膨胀过程,即从偏向锁到轻量级锁,再到重量级锁的转变。下面我们将详细介绍这一过程以及锁在内存中的变化。
37 4
|
7天前
|
Arthas 监控 Java
JVM进阶调优系列(9)大厂面试官:内存溢出几种?能否现场演示一下?| 面试就那点事
本文介绍了JVM内存溢出(OOM)的四种类型:堆内存、栈内存、元数据区和直接内存溢出。每种类型通过示例代码演示了如何触发OOM,并分析了其原因。文章还提供了如何使用JVM命令工具(如jmap、jhat、GCeasy、Arthas等)分析和定位内存溢出问题的方法。最后,强调了合理设置JVM参数和及时回收内存的重要性。
|
5天前
|
Java Linux Windows
JVM内存
首先JVM内存限制于实际的最大物理内存,假设物理内存无限大的话,JVM内存的最大值跟操作系统有很大的关系。简单的说就32位处理器虽然可控内存空间有4GB,但是具体的操作系统会给一个限制,这个限制一般是2GB-3GB(一般来说Windows系统下为1.5G-2G,Linux系统下为2G-3G),而64bit以上的处理器就不会有限制。
8 1
|
1月前
|
缓存 算法 Java
JVM知识体系学习六:JVM垃圾是什么、GC常用垃圾清除算法、堆内存逻辑分区、栈上分配、对象何时进入老年代、有关老年代新生代的两个问题、常见的垃圾回收器、CMS
这篇文章详细介绍了Java虚拟机(JVM)中的垃圾回收机制,包括垃圾的定义、垃圾回收算法、堆内存的逻辑分区、对象的内存分配和回收过程,以及不同垃圾回收器的工作原理和参数设置。
62 4
JVM知识体系学习六:JVM垃圾是什么、GC常用垃圾清除算法、堆内存逻辑分区、栈上分配、对象何时进入老年代、有关老年代新生代的两个问题、常见的垃圾回收器、CMS
|
1月前
|
存储 缓存 算法
JVM核心知识点整理(内存模型),收藏再看!
JVM核心知识点整理(内存模型),收藏再看!
JVM核心知识点整理(内存模型),收藏再看!
|
24天前
|
存储 算法 Java
聊聊jvm的内存结构, 以及各种结构的作用
【10月更文挑战第27天】JVM(Java虚拟机)的内存结构主要包括程序计数器、Java虚拟机栈、本地方法栈、Java堆、方法区和运行时常量池。各部分协同工作,为Java程序提供高效稳定的内存管理和运行环境,确保程序的正常执行、数据存储和资源利用。
46 10
|
23天前
|
存储 算法 Java
Java虚拟机(JVM)的内存管理与性能优化
本文深入探讨了Java虚拟机(JVM)的内存管理机制,包括堆、栈、方法区等关键区域的功能与作用。通过分析垃圾回收算法和调优策略,旨在帮助开发者理解如何有效提升Java应用的性能。文章采用通俗易懂的语言,结合具体实例,使读者能够轻松掌握复杂的内存管理概念,并应用于实际开发中。
|
1月前
|
存储 监控 算法
JVM调优深度剖析:内存模型、垃圾收集、工具与实战
【10月更文挑战第9天】在Java开发领域,Java虚拟机(JVM)的性能调优是构建高性能、高并发系统不可或缺的一部分。作为一名资深架构师,深入理解JVM的内存模型、垃圾收集机制、调优工具及其实现原理,对于提升系统的整体性能和稳定性至关重要。本文将深入探讨这些内容,并提供针对单机几十万并发系统的JVM调优策略和Java代码示例。
49 2
|
1月前
|
存储 Java
JVM知识体系学习四:排序规范(happens-before原则)、对象创建过程、对象的内存中存储布局、对象的大小、对象头内容、对象如何定位、对象如何分配
这篇文章详细地介绍了Java对象的创建过程、内存布局、对象头的MarkWord、对象的定位方式以及对象的分配策略,并深入探讨了happens-before原则以确保多线程环境下的正确同步。
53 0
JVM知识体系学习四:排序规范(happens-before原则)、对象创建过程、对象的内存中存储布局、对象的大小、对象头内容、对象如何定位、对象如何分配
|
1月前
|
Java API 对象存储
JVM进阶调优系列(2)字节面试:JVM内存区域怎么划分,分别有什么用?
本文详细解析了JVM类加载过程的关键步骤,包括加载验证、准备、解析和初始化等阶段,并介绍了元数据区、程序计数器、虚拟机栈、堆内存及本地方法栈的作用。通过本文,读者可以深入了解JVM的工作原理,理解类加载器的类型及其机制,并掌握类加载过程中各阶段的具体操作。