GC是什么?为什么要GC?

GC( Garbage Collection ),垃圾回收,是Java与C++的主要区别之一。作为Java开发者,一般不需要专门编写内存回收和垃圾清理代码。这是因为在Java虚拟机中,存在自动内存管理和垃圾清理机制。对JVM中的内存进行标记,并确定哪些内存需要回收,根据一定的回收策略,自动的回收内存,保证JVM中的内存空间,防止出现内存泄露和溢出问题。

GC是任意时候都能进行的吗

GC垃圾收集只能在安全点才能进行。在Java虚拟机(JVM)中,安全点(Safe Point)是程序执行的某些特定位置。JVM只能在安全点安全地暂停执行,从而进行垃圾回收(GC)等操作。安全点的设定确保了当线程暂停时,程序的状态是可知和一致的。

如何判断一个对象是否存活?

引用计数法

给对象中添加一个引用计数器,每当有一个地方引用它,计数器就加 1;当引用失效,计数器就减 1;任何时候计数器为 0 的对象就是不可能再被使用的。

优点:可即刻回收垃圾,当对象计数为0时,会立刻回收;

弊端:循环引用时,两个对象的计数都为1,导致两个对象都无法被释放。JVM不用这种算法

可达性分析算法

通过 GC Root 对象为起点,从这些节点向下搜索,搜索所走过的路径叫引用链,当一个对象到 GC Root没有任何的引用链相连时,说明这个对象是不可用的。

  • JVM中的垃圾回收器通过可达性分析来探索所有存活的对象

  • 扫描堆中的对象,看能否沿着GC Root对象为起点的引用链找到该对象,如果找不到,则表示可以回收

GC Root的对象有哪些?

  • 虚拟机栈(栈帧中的本地变量表)中引用的对象,例如各个线程被调用的方法栈用到的参数、局部变量或者临时变量等。

  • 方法区中类静态属性引用的对象或者说Java类中的引用类型的静态变量。

  • 方法区中常量引用的对象或者运行时常量池中的引用类型变量。

  • 本地方法栈中JNI(即一般说的Native方法)引用的对象

  • JVM内部的内存数据结构的一些引用、同步的监控对象(被修饰同步锁)。

finalize()方法的作用?

finalize() 类似 C++ 的析构函数,用来做关闭外部资源等工作。但是 try-finally 等方式可以做的更好,并且该方法运行代价高昂,不确定性大,无法保证各个对象的调用顺序,因此最好不要使用。(Java 9中已弃用)

当一个对象可被回收时,如果需要执行该对象的 finalize() 方法,那么就有可能通过在该方法中让对象重新被引用,从而实现自救。自救只能进行一次,如果回收的对象之前调用了 finalize() 方法自救,后面回收时不会调用 finalize() 方法。

Java种有哪些引用类型?有什么特点?

  • 强引用:gc时不会回收

  • 软引用:只有在内存不够用时,gc才会回收

  • 弱引用:只要gc就会回收;弱引用对象非常适合于实现 Map 的缓存(weakHashMap),当对象只通过弱引用可达时,可以快速释放内存。

  • 虚引用:是否回收都找不到引用的对象,仅用于管理直接内存

什么时候需要安全点?安全点的触发条件?

安全点的作用:

  • 垃圾收集: 在进行垃圾收集时,JVM需要暂停所有应用程序线程(GC暂停),以确保不会有线程在操作内存。同时,状态的快照是确定的,以便于GC工作。
  • 堆栈遍历: 在执行如线程转储(Thread Dump)等操作时,JVM需要安全地遍历线程栈,这时也需要安全点。
  • 性能损耗最小化: 通过在最可能长时间运行的指令设置安全点(例如循环的末端、方法的调用与返回),JVM可以减少程序暂停的频率,从而降低性能损耗。

安全点的触发条件:

  1. 方法调用:每次方法调用都是一个潜在的安全点。
  2. 循环回跳:长时间循环中间会插入安全点检查。
  3. 异常处理:处理异常时,也会检查是否到达安全点。

young Gc、old Gc、full Gc 和 mixed Gc 的区别是什么?

Young GC(Minor GC或 YGC),即年轻代垃圾回收:

  • 作用范围:仅针对新生代(Eden和S0/S1)。
  • 触发条件:当新生代内存(尤其是 Eden 区)被填满时触发。
  • 执行方式:只回收新生代中的对象,老年代不受影响。
  • 特点:回收频率较高,回收时间较短,因为新生代中的对象大多数是短命对象,容易被回收。

Old Gc(Major GC或OGC),老年代垃圾回收:

  • 作用范围:只针对老年代。
  • 触发条件:当老年代空间不足时触发,通常是当从新生代晋升到老年代的对象过多,或者老年代的存活对象数量达到一定阈值时。
  • 执行方式:只回收老年代的对象,新生代不受影响。
  • 特点:执行时间比 Young GC 长,因为老年代中的对象存活时间更长,且数量较多

Full GC,全堆垃圾回收:

  • 作用范围:对整个堆内存(包括新生代和老年代)进行回收。
  • 触发条件:当老年代空间不足且无法通过老年代垃圾回收释放足够空间,或其他情况导致系统内存压力较大时触发(如 system.gc()调用)
  • 执行方式:回收所有代(新生代、老年代)中的垃圾,并且可能会伴随着元空间的回收。
  • 特点:回收时间最长,会触发整个JM 的停顿(Stop-The-World),对性能有较大影响,通常不希望频繁发生

Mixed Gc(仅适用于 G1 GC 的混合垃圾回收):

  • 作用范围:同时回收新生代和部分老年代区域
  • 触发条件:当 G1垃圾回收器发现老年代区域的垃圾过多时触发。
  • 执行方式:混合回收新生代和部分老年代区域,主要目的是减少老年代中的垃圾积压。
  • 特点:结合了 YGC 的快速回收和 OGC的深度回收,尽量减少停顿时间,适用于大内存应用

对象在堆中的生命周期?

  1. 在 JVM 内存模型的堆中,堆被划分为新生代和老年代

    • 新生代又被进一步划分为 Eden区Survivor区From SurvivorTo Survivor
  2. 当创建一个对象时,对象会被优先分配到新生代的 Eden 区

    • 此时 JVM 会给对象定义一个对象年轻计数器 -XX:MaxTenuringThreshold
  3. 当 Eden 空间不足时,JVM 将执行新生代的垃圾回收(Minor GC)

    • JVM 会把存活的对象转移到 Survivor 中,并且对象年龄 +1

    • 对象在 Survivor 中同样也会经历 Minor GC,每经历一次 Minor GC,对象年龄都会+1

  4. 如果分配的对象超过了 -XX:PetenureSizeThreshold 直接被分配到老年代

内存的分配策略?

  • 对象优先在 Eden 分配: 大多数情况下,对象在新生代 Eden 上分配,当 Eden 空间不够时,触发 Minor GC

  • 大对象直接进入老年代: 当遇到一个较大的对象时,就算新生代的伊甸园为空,也无法容纳该对象时,会将该对象直接晋升为老年代,最典型的大对象有长字符串和大数组。可以设置JVM参数 -XX:PretenureSizeThreshold ,大于此值的对象直接在老年代分配。

  • 长期存活的对象进入老年代: 通过参数 -XX:MaxTenuringThreshold 可以设置对象进入老年代的年龄阈值。对象在 Survivor 区每经过一次 Minor GC ,年龄就增加 1 岁,当它的年龄增加到一定程度,就会被晋升到老年代中。

  • 动态对象年龄判定: 并非对象的年龄必须达到 MaxTenuringThreshold 才能晋升老年代,如果在 Survivor 中相同年龄所有对象大小的总和大于 Survivor 空间的一半,则年龄大于或等于该年龄的对象可以直接进入老年代,无需达到 MaxTenuringThreshold 年龄阈值。

  • 空间分配担保: 在发生 Minor GC 之前,虚拟机先检查老年代最大可用的连续空间是否大于新生代所有对象总空间,如果条件成立的话,那么 Minor GC 是安全的。如果不成立的话虚拟机会查看HandlePromotionFailure 的值是否允许担保失败。如果允许,那么就会继续检查老年代最大可用的连续空间是否大于历次晋升到老年代对象的平均大小,如果大于,将尝试着进行一次 Minor GC,尽管这次Minor GC是有风险的;(也就是说,会把原先新生代的对象挪到老年代中) ;如果小于,或者 HandlePromotionFailure 的值为不允许担保失败,那么就要进行一次 Full GC 。

空间分配担保时的 “冒险”是冒了什么风险?

新生代使用复制收集算法,但为了内存利用率,只使用其中一个Survivor空间来作为轮换备份,因此当出现大量对象在Minor GC后仍然存活的情况(最极端的情况就是内存回收后新生代中所有对象都存活),就需要老年代进行分配担保,把Survivor无法容纳的对象直接进入老年代。但前提是老年代本身还有容纳这些对象的剩余空间,一共有多少对象会活下来在实际完成内存回收之前是无法明确知道的,所以只好取之前每一次回收晋升到老年代对象容量的平均大小值作为经验值,与老年代的剩余空间进行比较,决定是否进行Full GC来让老年代腾出更多空间。

取平均值进行比较其实仍然是一种动态概率的手段,也就是说,如果某次Minor GC存活后的对象突增,远远高于平均值的话,依然会导致担保失败(Handle Promotion Failure)。如果出现了HandlePromotionFailure失败,那就只好在失败后重新发起一次Full GC。虽然担保失败时绕的圈子是最大的,但大部分情况下都还是会将HandlePromotionFailure开关打开,避免Full GC过于频繁。

Young GC的触发条件

在Java 中,Young GC(Minor GC)是针对新生代(Young Generation)对象的垃圾回收。主要有三种情况会会触发 Young GC:

  • Eden 区空间不足:新生代被划分为三个区域,Eden区、S0(Survivor0)区和S1(Survivor 1)区,大部分新创建的对象会先分配到 Eden 区。当 Eden 区的对象填满,无法再为新的对象分配空间时,Young GC 会被触发,回收新生代中不再使用的对象。
  • Eden 区+Survivor 区都装满:如果 Eden 区和 Survivor 区的空间都不足以存放新分配的对象时,Young GC 也会被触发,清理空间并将幸存的对象转移到 Survivor 区或老年代
  • 部分垃圾回收器在 full gc 之前:有一些收集器的回收实现是在 full gc 前会让先执行以下 young gc。比如 Parallel Scavenge,不过有参数可以调整让其不进行 young gc。

Full GC 的触发条件?

对于 Minor GC,其触发条件非常简单,当 Eden 空间满时,就将触发一次 Minor GC。而 Full GC 则相对复杂,有以下条件:•

  • 用 System.gc(): 只是建议虚拟机执行 Full GC,但是虚拟机不一定真正去执行。不建议使用这种方式,而是让虚拟机管理内存。

  • 老年代空间不足: 老年代空间不足的常见场景为前文所讲的大对象直接进入老年代、长期存活的对象进入老年代等。为了避免以上原因引起的 Full GC,应当尽量不要创建过大的对象以及数组、注意编码规范避免内存泄露。除此之外,可以通过 -Xmn 参数调大新生代的大小,让对象尽量在新生代被回收掉,不进入老年代。还可以通过 -XX:MaxTenuringThreshold 调大对象进入老年代的年龄,让对象在新生代多存活一段时间。

  • 空间分配担保失败: 当程序创建一个大对象时,Eden区域放不下大对象,使用复制算法的 Minor GC 需要老年代的内存空间作担保,如果担保失败会执行一次 Full GC。

  • JDK 1.7 及以前的永久代空间不足: 在 JDK 1.7 及以前,HotSpot 虚拟机中的方法区是用永久代实现的,永久代中存放的为一些 Class 的信息、常量、静态变量等数据。当系统中要加载的类、反射的类和调用的方法较多时,永久代可能会被占满,在未配置为采用 CMS GC 的情况下也会执行 Full GC。如果经过 Full GC 仍然回收不了,那么虚拟机会抛出 java.lang.OutOfMemoryError 。(JDK 8以后元空间不足

  • Concurrent Mode Failure:执行 CMS GC 的过程中同时有对象要放入老年代,而此时老年代空间不足(可能是 GC 过程中浮动垃圾过多导致暂时性的空间不足),便会报 Concurrent Mode Failure 错误,并触发 Full GC。

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

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

相关文章

FDMA读写AXI BRAM交互:FPGA高速数据传输的核心技术

在图像处理系统中,当1080P视频流以每秒60帧的速度传输时,传统DMA每帧会浪费27%的带宽在地址管理上——而FDMA技术能将这些损失降至3%以内 现代FPGA系统中,高效数据搬运往往是性能瓶颈的关键所在。当你在手机上流畅播放4K视频、在自动驾驶系统中实时处理激光雷达点云时,背后…

独立开发A/B测试实用教程

A/B测试(A/B Testing),又称分组测试、对照实验,是产品开发和运营中提升转化率、优化用户体验的常用方法。无论你是做App、SaaS、网站还是小程序,合理地利用A/B测试,都能帮助你用数据驱动决策,让…

如何将iPhone备份到Mac/MacBook

许多iPhone用户非常重视备份,但在Mac上选择合适的备份方法可能会令人困惑。市场上有各种各样的备份工具,找到一个既易于使用又能保存所有重要数据(如照片、视频、消息、WhatsApp聊天记录和联系人)的工具至关重要。如果你正在寻找一…

Logseq 插件开发实战四:发布到官方插件市场

🚩系列回顾 初识插件机制并实现自动压缩粘贴的图片国际化 I18N 与配置多语言自定义斜线命令 SlashCommand发布到官方插件市场 开源地址:logseq-plugin-image-tiny,欢迎来⭐。 🐞 插件上线问题记录 问题描述 本地插件开发完成后…

[netty5: ByteToMessageCodec MessageToByteEncoder ByteToMessageDecoder]-源码分析

ByteToMessageCodec ByteToMessageCodec 是一个结合了 ByteToMessageDecoder 和 MessageToByteEncoder 的编解码器&#xff0c;可以实时地将字节流编码或解码为消息&#xff0c;反之亦然。 public abstract class ByteToMessageCodec<I> extends ChannelHandlerAdapter {…

Ubuntu20.04安装mujoco210, mujoco-py时的报错处理

参考 Ubantu 20.04 安装 Mujoco210、mujoco-py、gym及报错解决 安装 mujoco210 创建 .mujoco 文件夹 mkdir ~/.mujoco亲测必须是 .mujoco 文件夹&#xff0c;不然会报错&#xff01; 下载 mujoco210-linux-x86_64.tar.gz 并解压到 .mujoco 文件夹 mojoco下载地址 测试 mojo…

全志T507 音频ALSA核心层注册流程分析

一.ALSA核心层注册流程分析 驱动目录&#xff1a;kernel-4.9/sound/core/sound.c struct file_operations snd_fops {.owner THIS_MODULE,.open snd_open, (inode, file)---->struct snd_minor *mptr snd_minors[minor];---->file->f_op fops_get(mptr->f_ops…

评论区实现 前端Vue

根据后端部分定义评论区功能实现 golang后端部分-CSDN博客&#xff0c;重点需要实现三个部分&#xff0c;1.当前用户发起新根评论请求&#xff1b;2.评论区展示部分&#xff1b;3.某一根评论的子评论展示以及回复组件显示。 整体流程解释 数据从后端接收&#xff0c;整体在in…

差分定位技术:原理、分类与应用场景

文章目录 简介基本概念位置差分伪距差分载波相位 差分定位技术精密单点定位&#xff08;PPP&#xff09;差分全球定位系统&#xff08;DGPS&#xff09;实时动态定位&#xff08;RTK&#xff09; 应用场景总结 简介 差分定位&#xff08;Differential Positioning&#xff09;是…

tomcat的tar包转换成rpm包的保姆级教程

环境说明 &#xff1a;centos 71. 安装打包工具&#xff1a;yum install -y rpm-build rpmdevtools2. 创建 RPM 打包环境&#xff1a;rpmdev-setuptree​输入之后是下面的结果~/rpmbuild/ ├── BUILD ├── RPMS ├── SOURCES ├── SPECS └── SRPMS​准备 Tomcat 源码…

【牛客算法】小美的数组删除

文章目录 一、题目介绍二、解题思路三、解题算法实现四、算法分析4.1 代码逻辑4.2 逆向遍历求MEX的设计精妙之处4.2.1 逆向遍历:解决MEX更新的连续性4.2.2 利用MEX的单调性4.2.3 空间复用与状态压缩4.2.4 与问题特性的完美契合4.2.5 总结:为什么说这个设计“妙”?五、算法复…

MyBatisPlus-01-环境初始化及简单应用

文章目录【README】【1】springboot集成mybatis-plus配置【1.1】目录结构【相关说明】【1.2】代码示例【pom.xml】【application.properties】【MybatisPlusNoteController】【UserAppService】【UserMapper】【UserPO】【建表语句】【2】演示【README】 本文代码参见&#xf…

Web爬虫编程语言选择指南

刚学爬虫的小伙伴常常为选择那种语言来写爬虫而烦恼&#xff0c;今天我将总结几种语言的优劣势&#xff0c;然后选择适合编写 Web爬虫 的编程语言。这就需要我们考虑开发效率、生态库支持、并发性能等因素。以下是主流选择及特点跟着一起看看吧&#xff1a; 1. Python&#xff…

学习日志06 python

加油&#xff0c;今天的任务是学习面向对象编程&#xff0c;设计一个简单的宠物管理系统&#xff08;宠物类、猫 / 狗子类&#xff09;&#xff0c;先做5道题目开启学习状态吧&#xff01;1 setdefault()在 Python 中&#xff0c;setdefault() 是字典&#xff08;dict&#xff…

基于Java+springboot 的车险理赔信息管理系统

源码、数据库、包调试源码编号&#xff1a;S595源码名称&#xff1a;基于springboot 的车险理赔信息管理系统用户类型&#xff1a;多角色&#xff0c;用户、事故调查员、管理员数据库表数量&#xff1a;14 张表主要技术&#xff1a;Java、Vue、ElementUl 、SpringBoot、Maven运…

MyDockFinder 绿色便携版 | 一键仿Mac桌面,非常简单

如果你既不想升级到Win11&#xff0c;又想体验Mac桌面的高级感&#xff0c;那么MyDockFinder将是你的最佳选择。这是一款专为Windows系统设计的桌面美化工具&#xff0c;能够将你的桌面转变成MacOS的风格。它提供了类似Dock栏和Finder的功能&#xff0c;让你在不更换操作系统的…

Babylon.js 材质克隆与纹理共享:你可能遇到的问题及解决方案

在 Babylon.js 中&#xff0c;材质&#xff08;Material&#xff09;和纹理&#xff08;Texture&#xff09;的克隆行为可能会影响渲染性能和内存管理&#xff0c;尤其是在多个材质共享同一纹理的情况下。本文将探讨&#xff1a;PBRMetallicRoughnessMaterial 的克隆机制&#…

信息素养复赛模拟1和模拟2的编程题标程

信息素养复赛模拟 11&#xff1a;楼层编号 #include<bits/stdc.h> using namespace std; int main(){int n, t;cin >> n >> t;int res 0;for(int i 1; i < n; i ){int x i;bool ok true;while(x){if(x % 10 t){ok false;}x / 10;}res ok;} cout &l…

Hadoop高可用集群搭建

Hadoop高可用(HA)集群是企业级大数据平台的核心基础设施&#xff0c;通过多主节点冗余和自动故障转移机制&#xff0c;确保系统在单点故障时仍能正常运行。本文将详细介绍如何基于CentOS 7搭建Hadoop 3.X高可用集群&#xff0c;涵盖环境准备、组件配置、集群启动及管理的全流程…

Next.js 实战笔记 1.0:架构重构与 App Router 核心机制详解

Next.js 实战笔记 1.0&#xff1a;架构重构与 App Router 核心机制详解 上一次写 Next 相关的东西都是 3 年前的事情了&#xff0c;这 3 年里 Next 也经历了 2-3 次的大版本变化。当时写的时候 Next 是 12 还是 13 的&#xff0c;现在已经是 15 了&#xff0c;从 build 到实现…