JVM 中的完整 GC 流程

一、引言

在 Java 应用程序的运行过程中,垃圾回收是一个至关重要的环节。它负责自动管理内存,回收不再被使用的对象,以确保应用程序的稳定运行。了解 JVM 中一次完整的 GC 流程对于优化 Java 应用的性能、减少内存占用以及避免内存泄漏至关重要。本文将深入探讨 JVM 中的 GC 流程。

二、JVM 内存结构概述

(一)堆内存

  1. 新生代(Young Generation)
    • Eden 区:新创建的对象首先分配在 Eden 区。
    • Survivor 区:分为 From Survivor 和 To Survivor 两个区域,用于存放经过一次 Minor GC 后仍然存活的对象。
  2. 老年代(Old Generation):存放经过多次 Minor GC 后仍然存活的对象。

(二)方法区(Metaspace)

存储类信息、常量、静态变量等数据。

(三)程序计数器、虚拟机栈和本地方法栈

用于存储线程的执行状态和局部变量等信息。

三、GC 类型

(一)Minor GC

  1. 触发条件
    • 当 Eden 区满时,触发 Minor GC。
  2. 作用范围
    • 主要清理新生代中的垃圾对象。

(二)Major GC/Full GC

  1. 触发条件
    • 老年代空间不足时触发 Major GC 或 Full GC。
    • 永久代(在 Java 8 后被 Metaspace 替代)空间不足时也可能触发 Full GC。
    • 显示调用 System.gc () 时可能触发 Full GC,但不建议在生产环境中使用。
  2. 作用范围
    • 清理整个堆内存,包括新生代和老年代。

四、Minor GC 流程

(一)标记阶段

  1. 可达性分析
    • 从根对象(如线程栈中的局部变量、静态变量等)开始,通过引用链遍历所有可达的对象。
    • 不可达的对象被标记为垃圾。
  2. 三色标记法
    • 白色:表示未被访问过的对象。
    • 灰色:表示对象已经被访问过,但它的引用还没有被完全处理。
    • 黑色:表示对象已经被访问过,并且它的引用也已经被完全处理。

(二)复制阶段

  1. 将 Eden 区和 From Survivor 区中存活的对象复制到 To Survivor 区。
  2. 如果对象的年龄达到一定阈值(默认是 15),则将其晋升到老年代。

(三)清理阶段

  1. 清理 Eden 区和 From Survivor 区中的垃圾对象。
  2. 将 From Survivor 区和 To Survivor 区互换角色,为下一次 Minor GC 做准备。

五、Major GC/Full GC 流程

(一)标记阶段

  1. 与 Minor GC 的标记阶段类似,采用可达性分析和三色标记法对整个堆内存中的对象进行标记。
  2. 由于老年代中的对象通常比较多,标记过程可能会比较耗时。

(二)整理阶段

  1. 对于老年代中的垃圾对象,进行清理。
  2. 可能会对存活的对象进行整理,以减少内存碎片。整理的方式可以是移动存活的对象,使它们连续存储。

(三)Metaspace 的清理(如果需要)

  1. 如果 Metaspace 空间不足,也可能触发 Full GC,此时会对 Metaspace 中的无用类信息等进行清理。

六、GC 触发条件的详细分析

(一)堆内存使用情况

  1. 新生代空间不足
    • 当 Eden 区和 Survivor 区中的对象占用空间超过一定比例时,触发 Minor GC。
    • 可以通过调整 JVM 参数来控制新生代的大小和比例,如 -Xmn 用于设置新生代的大小。
  2. 老年代空间不足
    • 当老年代中的对象占用空间超过一定比例时,触发 Major GC 或 Full GC。
    • 可以通过调整 JVM 参数来控制老年代的大小,如 -Xms 和 -Xmx 用于设置堆内存的初始大小和最大大小。

(二)对象的生命周期

  1. 对象的年龄增长
    • 对象在新生代中经过一次 Minor GC 后仍然存活,它的年龄会增加。当对象的年龄达到一定阈值时,会被晋升到老年代。
    • 可以通过调整 JVM 参数 -XX:MaxTenuringThreshold 来控制对象晋升到老年代的年龄阈值。
  2. 大对象直接进入老年代
    • 如果创建的对象占用空间较大,可能会直接进入老年代。可以通过调整 JVM 参数 -XX:PretenureSizeThreshold 来控制大对象的大小阈值。

(三)其他触发因素

  1. System.gc () 的调用
    • 在代码中显式调用 System.gc () 可能会触发 Full GC,但不建议在生产环境中使用,因为它会影响应用程序的性能。
  2. JVM 自身的策略
    • JVM 可能会根据一些内部策略触发 GC,如为了避免内存溢出等情况。

七、GC 算法详解

(一)标记 - 清除算法(Mark-Sweep)

  1. 算法原理
    • 标记阶段:通过可达性分析标记出所有存活的对象。
    • 清除阶段:清理所有未被标记的对象,释放内存空间。
  2. 优缺点
    • 优点:实现简单。
    • 缺点:会产生内存碎片,可能导致后续分配大对象时需要进行额外的整理操作。

(二)标记 - 整理算法(Mark-Compact)

  1. 算法原理
    • 标记阶段:与标记 - 清除算法相同。
    • 整理阶段:将所有存活的对象移动到一端,然后清理另一端的垃圾对象,从而避免内存碎片的产生。
  2. 优缺点
    • 优点:不会产生内存碎片。
    • 缺点:整理过程比较耗时,可能会影响应用程序的性能。

(三)复制算法(Copying)

  1. 算法原理
    • 将内存分为两块相等的区域,如新生代中的 Eden 区和 Survivor 区。当进行垃圾回收时,将存活的对象复制到另一块区域,然后清理原来的区域。
  2. 优缺点
    • 优点:实现简单,不会产生内存碎片。
    • 缺点:需要双倍的内存空间,当对象存活率较高时,复制操作会比较耗时。

八、实际案例分析

(一)案例背景

假设有一个 Java 应用程序,在运行过程中出现了频繁的 Full GC,导致应用程序性能下降。

(二)问题分析

  1. 通过监控工具(如 JVisualVM、jstat 等)观察堆内存的使用情况,发现老年代空间不足是触发 Full GC 的主要原因。
  2. 进一步分析发现,应用程序中存在一些大对象的创建,这些大对象直接进入老年代,导致老年代空间快速增长。
  3. 同时,应用程序中的某些对象的生命周期较长,经过多次 Minor GC 后仍然存活,最终晋升到老年代,也加剧了老年代空间的压力。

(三)解决方案

  1. 调整 JVM 参数
    • 增大堆内存的大小,如 -Xms 和 -Xmx,可以缓解老年代空间不足的问题,但要注意不要设置得过大,以免导致系统资源浪费。
    • 调整新生代和老年代的比例,如 -XX:NewRatio,可以适当增大新生代的空间,减少对象晋升到老年代的频率。
    • 调整对象晋升到老年代的年龄阈值,如 -XX:MaxTenuringThreshold,可以根据应用程序的实际情况适当降低年龄阈值,避免对象过早晋升到老年代。
  2. 优化对象创建
    • 避免创建不必要的大对象,如果确实需要创建大对象,可以考虑采用分块处理的方式,减少大对象对老年代的压力。
  3. 对象生命周期管理
    • 对于生命周期较长的对象,可以考虑采用对象池等技术,避免频繁地创建和销毁对象,减少对象晋升到老年代的机会。

九、GC 优化策略

(一)合理设置 JVM 参数

  1. 根据应用程序的特点和需求,合理设置堆内存的大小、新生代和老年代的比例、对象晋升年龄阈值等参数。
  2. 可以通过压力测试和性能监控来调整 JVM 参数,找到最适合应用程序的参数组合。

(二)对象生命周期管理

  1. 尽量减少不必要的对象创建,避免创建大量短期存活的对象,减少 Minor GC 的频率。
  2. 对于生命周期较长的对象,可以采用对象池等技术进行管理,提高对象的复用率。

(三)避免内存泄漏

  1. 及时释放不再使用的对象引用,避免内存泄漏。
  2. 对资源的使用(如数据库连接、文件流等)要及时关闭,防止资源泄漏导致内存占用过高。

(四)选择合适的 GC 算法

  1. 根据应用程序的特点选择合适的 GC 算法。例如,如果应用程序对响应时间要求较高,可以选择并发收集器;如果应用程序对吞吐量要求较高,可以选择并行收集器。
  2. 在 Java 8 及以上版本中,可以使用 G1 收集器,它在兼顾吞吐量和响应时间方面表现较好。

十、总结

JVM 中的垃圾回收是一个复杂而重要的过程。了解一次完整的 GC 流程对于优化 Java 应用程序的性能至关重要。通过合理设置 JVM 参数、管理对象生命周期、避免内存泄漏以及选择合适的 GC 算法,可以有效地减少 GC 的频率和时间,提高应用程序的性能和稳定性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/471141.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

git下载慢下载不了?Git国内国外下载地址镜像,git安装视频教程

git安装下载的视频教程在这 3分钟完成git下载和安装,git国内外下载地址镜像,Windows为例_哔哩哔哩_bilibili 一、Git安装包国内和国外下载地址镜像 1.1国外官方下载地址 打开Git的官方网站:Git官网下载页面。在页面上选择对应的系统&…

专题十八_动态规划_斐波那契数列模型_路径问题_算法专题详细总结

目录 动态规划 动态规范五步走: 1. 第 N 个泰波那契数(easy) 解析: 1.状态表达式: 2.状态转移方程: 3.初始化: 4.填表顺序: 5.返回值 编写代码: 总结&#xff…

阿里云centos7.9服务器磁盘挂载,切换服务路径

项目背景 1、项目使用的服务器为阿里云centos7.9,默认的磁盘为vda,文件系统挂载在这个磁盘上,项目上使用的文件夹为/home/hnst/uploadPath 2、vda使用率已达到91% 3、现购置一块新的磁盘为vdb,大小为2T 目的 切换服务所使用的…

STM32问题集

这里写目录标题 一、烧录1、 Can not connect to target!【ST-LINK烧录】 一、烧录 1、 Can not connect to target!【ST-LINK烧录】 烧录突然 If the target is in low power mode, please enable “Debug in Low Power mode” option from Target->settings menu 然后就&…

Scala学习记录,case class,迭代器

case class case class创建的对象的属性是不可改的 创建对象,可以不用写new 自动重写:toString, equals, hashCode, copy 自动重写方法:toString,equals,hashCode,copy 小习一下 1.case class 的定义语法是什么 基本形式:case …

成都睿明智科技有限公司解锁抖音电商新玩法

在这个短视频风起云涌的时代,抖音电商以其独特的魅力迅速崛起,成为众多商家争夺的流量高地。而在这片充满机遇与挑战的蓝海中,成都睿明智科技有限公司犹如一颗璀璨的新星,以其专业的抖音电商服务,助力无数品牌实现从零…

阅读2020-2023年《国外军用无人机装备技术发展综述》笔记_技术趋势

目录 文献基本信息 序言 1 发展概况 2 重点技术发展 2.1 人工智能技术 2.1.1 应用深化 2.1.2 作战效能提升 2.2 航空技术 2.2.1螺旋桨设计创新 2.2.2 发射回收技术进步 2.3 其他相关技术 2.3.1 远程控制技术探 2.3.2 云地控制平台应用 3 装备系统进展 3.1 无人作…

LeetCode 86.分隔链表

题目: 给你一个链表的头节点 head 和一个特定值 x ,请你对链表进行分隔,使得所有 小于 x 的节点都出现在 大于或等于 x 的节点之前。 你应当 保留 两个分区中每个节点的初始相对位置。 思路: 代码: /*** Definiti…

SystemVerilog学习笔记(六):控制流

条件语句 条件语句用于检查块中的语句是否被执行。条件语句创建语句块。如果给出的表达式是 true,执行块中的语句集,如果表达式为 false,则 else 块语句将最后执行。 序号条件语句1.if2.if-else3.if-else ladder4.unique if5.unique0 if6.p…

SQL,力扣题目1127, 用户购买平台

一、力扣链接 LeetCode_1127 二、题目描述 支出表: Spending ---------------------- | Column Name | Type | ---------------------- | user_id | int | | spend_date | date | | platform | enum | | amount | int | ------------------…

【计算机网络】【传输层】【习题】

计算机网络-传输层-习题 文章目录 10. 图 5-29 给出了 TCP 连接建立的三次握手与连接释放的四次握手过程。根据 TCP 协议的工作原理,请填写图 5-29 中 ①~⑧ 位置的序号值。答案技巧 注:本文基于《计算机网络》(第5版)吴功宜、吴英…

群控系统服务端开发模式-应用开发-前端个人信息功能

个人信息功能我把他分为了3部分:第一部分是展示登录者信息;第二步就是登录者登录退出信息;第三部分就是修改个人资料。 一、展示登录者信息 1、优先添加固定路由 在根目录下src文件夹下route文件夹下index.js文件中,添加如下代码 …

Qwen2-VL:发票数据提取、视频聊天和使用 PDF 的多模态 RAG 的实践指南

概述 随着人工智能技术的迅猛发展,多模态模型在各类应用场景中展现出强大的潜力和广泛的适用性。Qwen2-VL 作为最新一代的多模态大模型,融合了视觉与语言处理能力,旨在提升复杂任务的执行效率和准确性。本指南聚焦于 Qwen2-VL 在三个关键领域…

Java面向对象高级2

1.代码块 2.内部类 成员内部类 public class Demo{public static void main(String[] args) {outer.inner innew outer().new inner();in.run();}}class outer{private String str"outer";public class inner{public void run(){String sstr;System.out.println(s);…

Elasticsearch 8.16:适用于生产的混合对话搜索和创新的向量数据量化,其性能优于乘积量化 (PQ)

作者:来自 Elastic Ranjana Devaji, Dana Juratoni Elasticsearch 8.16 引入了 BBQ(Better Binary Quantization - 更好的二进制量化)—— 一种压缩向量化数据的创新方法,其性能优于传统方法,例如乘积量化 (Product Qu…

androidstudio下载gradle慢

1,现象: 2,原因,国内到国外网址慢 3,解决方法:更改gradle-wrapper.properties #Wed Sep 26 20:01:52 CST 2018 distributionBaseGRADLE_USER_HOME distributionPathwrapper/dists zipStoreBaseGRADLE_USER…

浅谈:基于三维场景的视频融合方法

视频融合技术的出现可以追溯到 1996 年 , Paul Debevec等 提出了与视点相关的纹理混合方法 。 也就是说 , 现实的漫游效果不是从摄像机的角度来看 , 但其仍然存在很多困难 。基于三维场景的视频融合 , 因其直观等特效在视频监控等相关领域有着…

探索Python的HTTP利器:Requests库的神秘面纱

文章目录 **探索Python的HTTP利器:Requests库的神秘面纱**一、背景:为何选择Requests库?二、Requests库是什么?三、如何安装Requests库?四、Requests库的五个简单函数使用方法1. GET请求2. POST请求3. PUT请求4. DELET…

【算法一周目】双指针(2)

目录 有效三角形的个数 解题思路 C代码实现 和为s的两个数字 解题思路 C代码实现 三数之和 解题思路 C代码实现 四数之和 解题思路 C代码实现 有效三角形的个数 题目链接:611. 有效三角形的个数题目描述:给定一个包含非负整数的数组nums&…

基于Python的网上银行综合管理系统

作者:计算机学姐 开发技术:SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等,“文末源码”。 专栏推荐:前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏:…