JVM的GC机制和常见GC算法

简介: @[toc]1. 堆内存的分代2. GC分类3. 什么是GC3.1 需要GC的内存区域3.2 GC回收的对象3.3 判断对象存活的两种算法3.3.1 引用计数3.3.2 可达性分析3.4 什么时候触发GC4. 常见的GC算法4.1 标记-清除算法4.2 复制算法4.3 标记-压缩算法

1. 堆内存的分代

堆中内存分为新生代和老年代,其中新生代又分为Eden区、(Survivor)from区、(Survivor)To区


32.png


2. GC分类

新生代垃圾回收器:Minor GC/Young GC

老年代垃圾回收器:Mojor GC/Old GC

整理回收:Full GC(回收堆区和方法区)


3. 什么是GC

垃圾收集(Garbage Collection)通常被称为GC

在程序运行时,内存空间是有限的,那么如何及时的把不再使用的对象清除将内存释放出来,这就是GC要做的事情


3.1 需要GC的内存区域

JVM中,程序计数器、虚拟机栈、本地方法栈都是随线程而生随线程而灭,栈帧随着方法的进入和退出做入栈和出栈操作,实现了自动内存清理,因此内存垃圾回收主要集中于Java堆和方法区,程序运行期间,这部分内存的分配和使用都是动态的


33.png


3.2 GC回收的对象

当一个对象已经没有存活时,GC就会自动对其进行回收

判断对象是否存活有两种方法:引用计数和可达性分析


3.3 判断对象存活的两种算法

3.3.1 引用计数

每一个对象都有一个引用计数属性,新增一个引用时该属性 +1,引用释放时该属性 -1,当该属性为0时代表该对象可以被回收。


这种方法实现简单,缺点也很明显:需要额外的内存来计数、运行时需要维护计数器、无法解决循环引用的问题


3.3.2 可达性分析

  • 基本思路

通过一系列被称为 “ GC Roots ” 的根对象作为起始节点集,从这些结点开始,通过引用关系向下搜索,搜索走过的路径被称为 “ 引用链 ”,如果某个对象到 GC Roots 没有任何引用链相连,就说明该对象不可达,即可被回收

如下图所示,对象4、5、6可被回收


34.png

要想理解可达性分析算法,就得想明白这几个问题:什么是对象可达、GC Roots 是什么、哪些对象可以作为 GC Roots


什么是对象可达


对象可达指的就是双方之间存在直接或间接的引用关系


GC Roots 是什么


GC Roots 就是 JVM 确定当前绝对不会被回收的对象,只要找到这种对象,此对象所依赖的其他对象肯定也不能被回收


哪些对象可被当作 GC Roots


方法区静态属性引用的对象


全局对象的一种,Class 对象本身很难被回收,只要 Class 对象不被回收,静态成员就不能被回收


方法区常量池引用的对象


也属于全局对象,常量本身初始化后不会改变,因此作为 GC Roots 也是合理的


被同步锁持有的对象


被 synchronized 锁住的对象是绝对不能回收的,GC 如果回收了对象,锁不就失效了嘛


3.4 什么时候触发GC

程序调用 System.gc 时触发

系统自身来决定GC触发的时机(根据Eden区和From Space区的内存大小来决定。当内存大小不足时,则会启动GC线程并停止应用线程)

GC又分为 minor GC 和 Full GC (也称为 Major GC )


Minor GC触发条件:当Eden区满时,触发Minor GC。


Full GC触发条件:


a.调用System.gc时,系统建议执行Full GC,但是不必然执行


b.老年代空间不足


c.方法去空间不足


d.通过Minor GC后进入老年代的平均大小大于老年代的可用内存


e.由Eden区、From Space区向To Space区复制时,对象大小大于To Space可用内存,则把该对象转存到老年代,且老年代的可用内存小于该对象大小


4. 常见的GC算法

4.1 标记-清除算法

该算法分为标记和清除两个阶段,标记就是把所有活动对象都做上标记的阶段,清除就是将没有做上标记的对象进行回收的阶段


4.2 复制算法

复制算法就是将内存空间按容量分成两块。当这一块内存用完时,就将存活着的对象复制到另一块上面,然后将已经使用过的一块一块清除掉


4.3 标记-压缩算法

标记-压缩算法与标记-清除算法类似,只是后续步骤是让所有存活的对象移动到一端,然后清除掉端边界以外的内存。


目录
相关文章
|
8天前
|
缓存 算法 Java
JVM知识体系学习六:JVM垃圾是什么、GC常用垃圾清除算法、堆内存逻辑分区、栈上分配、对象何时进入老年代、有关老年代新生代的两个问题、常见的垃圾回收器、CMS
这篇文章详细介绍了Java虚拟机(JVM)中的垃圾回收机制,包括垃圾的定义、垃圾回收算法、堆内存的逻辑分区、对象的内存分配和回收过程,以及不同垃圾回收器的工作原理和参数设置。
29 4
JVM知识体系学习六:JVM垃圾是什么、GC常用垃圾清除算法、堆内存逻辑分区、栈上分配、对象何时进入老年代、有关老年代新生代的两个问题、常见的垃圾回收器、CMS
|
8天前
|
Arthas 监控 Java
JVM知识体系学习七:了解JVM常用命令行参数、GC日志详解、调优三大方面(JVM规划和预调优、优化JVM环境、JVM运行出现的各种问题)、Arthas
这篇文章全面介绍了JVM的命令行参数、GC日志分析以及性能调优的各个方面,包括监控工具使用和实际案例分析。
25 3
|
8天前
|
缓存 前端开发 Java
JVM知识体系学习二:ClassLoader 类加载器、类加载器层次、类过载过程之双亲委派机制、类加载范围、自定义类加载器、编译器、懒加载模式、打破双亲委派机制
这篇文章详细介绍了JVM中ClassLoader的工作原理,包括类加载器的层次结构、双亲委派机制、类加载过程、自定义类加载器的实现,以及如何打破双亲委派机制来实现热部署等功能。
19 3
|
9天前
|
算法 Java
JVM进阶调优系列(4)年轻代和老年代采用什么GC算法回收?
本文详细介绍了JVM中的GC算法,包括年轻代的复制算法和老年代的标记-整理算法。复制算法适用于年轻代,因其高效且能避免内存碎片;标记-整理算法则用于老年代,虽然效率较低,但能有效解决内存碎片问题。文章还解释了这两种算法的具体过程及其优缺点,并简要提及了其他GC算法。
 JVM进阶调优系列(4)年轻代和老年代采用什么GC算法回收?
|
16天前
|
存储 算法 Java
【JVM】垃圾释放方式:标记-清除、复制算法、标记-整理、分代回收
【JVM】垃圾释放方式:标记-清除、复制算法、标记-整理、分代回收
39 2
|
8天前
|
存储 安全 Java
jvm 锁的 膨胀过程?锁内存怎么变化的
【10月更文挑战第3天】在Java虚拟机(JVM)中,`synchronized`关键字用于实现同步,确保多个线程在访问共享资源时的一致性和线程安全。JVM对`synchronized`进行了优化,以适应不同的竞争场景,这种优化主要体现在锁的膨胀过程,即从偏向锁到轻量级锁,再到重量级锁的转变。下面我们将详细介绍这一过程以及锁在内存中的变化。
23 4
|
2月前
|
Java Docker 索引
记录一次索引未建立、继而引发一系列的问题、包含索引创建失败、虚拟机中JVM虚拟机内存满的情况
这篇文章记录了作者在分布式微服务项目中遇到的一系列问题,起因是商品服务检索接口测试失败,原因是Elasticsearch索引未找到。文章详细描述了解决过程中遇到的几个关键问题:分词器的安装、Elasticsearch内存溢出的处理,以及最终成功创建`gulimall_product`索引的步骤。作者还分享了使用Postman测试接口的经历,并强调了问题解决过程中遇到的挑战和所花费的时间。
|
11天前
|
存储 缓存 算法
JVM核心知识点整理(内存模型),收藏再看!
JVM核心知识点整理(内存模型),收藏再看!
JVM核心知识点整理(内存模型),收藏再看!
|
7天前
|
存储 监控 算法
JVM调优深度剖析:内存模型、垃圾收集、工具与实战
【10月更文挑战第9天】在Java开发领域,Java虚拟机(JVM)的性能调优是构建高性能、高并发系统不可或缺的一部分。作为一名资深架构师,深入理解JVM的内存模型、垃圾收集机制、调优工具及其实现原理,对于提升系统的整体性能和稳定性至关重要。本文将深入探讨这些内容,并提供针对单机几十万并发系统的JVM调优策略和Java代码示例。
33 2
|
8天前
|
存储 Java
JVM知识体系学习四:排序规范(happens-before原则)、对象创建过程、对象的内存中存储布局、对象的大小、对象头内容、对象如何定位、对象如何分配
这篇文章详细地介绍了Java对象的创建过程、内存布局、对象头的MarkWord、对象的定位方式以及对象的分配策略,并深入探讨了happens-before原则以确保多线程环境下的正确同步。
24 0
JVM知识体系学习四:排序规范(happens-before原则)、对象创建过程、对象的内存中存储布局、对象的大小、对象头内容、对象如何定位、对象如何分配