GC(垃圾回收)详解

article/2025/9/19 14:24:25


JVM

  • 1.年轻代:年轻代主要存放新创建的对象,垃圾回收会比较频繁。(稍微讲细一点就是即可,年轻代分成Eden Space和Suvivor Space。当对象在堆创建时,将进入年轻代的Eden Space。垃圾回收器进行垃圾回收时,扫描Eden Space,如果对象仍然存活,则复制到Suvivor Space。)
  • 2.年老代:年老代主要存放JVM认为生命周期比较长的对象(在扫描Suvivor Space时,如果对象已经经过了几次的扫描仍然存活,JVM认为其为一个持久化对象,则将其移到Old Gen。)
  • 3.持久代:持久代主要存放类定义、字节码和常量等很少会变更的信息。



GC算法基础

1、引用计数法:无法解决循环引用的问题,不被java采纳

2、根搜索算法:从根结点扫描,只要这个对象在引用链中,那就是可触及的。

现代虚拟机中的垃圾搜索算法:

  • 标记清除
  • 复制算法(新生代)
  • 标记压缩(老年代)

这三种算法都扩充了根搜索算法。



1、标记清除算法

概念: 标记清除算法是现代垃圾回收算法的思想基础。标记清除将垃圾回收分为两个阶段:标记阶段和清除阶段。

  • 标记阶段:首先通过根结点,标记所有从根节点开始的可达对象。因此未被标记的对象就是未被引用的垃圾对象。
  • 清除阶段:在清除阶段,清除所有未被标记的对象。

7de44970-2e02-46a1-a5d0-0663b21906c6

实践: 在堆中的有效空间被耗尽时,就会停止整个程序(stop the world),然后进行标记清除。

  • 标记:遍历所有的GC Roots,然后将所有的GC Roots可达的对象标记为存活的对象。
  • 清除:清除的过程将遍历堆中的所有的对象,将没有标记的对象全部清除。

标记清除算法的缺点:

  • 等待时间长(递归与全堆对象遍历),导致stop the world的时间很长。
  • 不能解决内存碎片的问题



2、复制算法

概念: 将原有的内存空间分为两块,每次只使用其中的一块。在垃圾回收的时候,将存活对象复制到未使用的内存块中,之后,清除正在使用的内存块中的所有对象,交换两个内存的角色,完成垃圾回收。

ff1e1846-e49c-4663-aee1-7c63628f567c

不适用于存活对象较多的场合,如老年代(复制算法适合做新生代的GC),和标记清除算法相比解决了内存碎片的问题。

复制算法的缺点:

  • 空间浪费,复制算法每次都只对半区内存进行回收,复制算法要想使用,最起码对象的存活率要非常低才行,而且重要的是要克服50%的内存浪费。
  • 如果要应对所有对象都100%存活的极端情况,就必须要有很大的额外空间担保,所以这种算法不适用很多的对象存活率都很高的时候(老年代)。

新生代:Eden区、Surivor区(From区和to区)

http://ifeve.com/wp-content/uploads/2014/07/young_gc.png

现代商业虚拟机都采用这种收集算法来回收新生代,新生代中的对象98%都是“朝生夕死”的,所以并不需要1:1的比例来划分内存空间,而是将内存划分为一块比较大的Eden区和两块比较小的Surivor空间(From区和to区),每次使用Eden和其中一块Surivor。当回收的时候,先根据分代收集算法将年龄大的对象放入老年代,然后将Eden和Surivor中还存活着的对象一次性的复制到另一块Surivor空间上,最后清理掉Eden和刚才用过的Surivor空间。HotSpot虚拟机默认Eden和Surivor的大小比例是8:1,也就是说,每次新生代中可用内存空间为整个新生代容量的90%(80%+10%),只有10%的空间会被浪费。

当然,我们没法保证每次回收都只有不超过10%的对象存活,当Surivor空间不够用时,需要依赖于老年代进行分配,所以大对象直接进入老年代。如下图所示:

7e1f6ed2-e0c4-45e4-b7db-b59c28e1ee9c



3、标记-整理算法

概念: 在标记-清除算法的基础上做了一些优化,和标记-清除算法一样,首先需要从根结点开始,对所有可达对象做一次标记。但是之后,将所有存活的对象压缩到内存一端,然后清理边界外所有的空间。

https://images0.cnblogs.com/blog/641601/201508/201003005357866.png

实践:

  • 标记:遍历所有的GC Roots,然后将所有的GC Roots可达的对象标记为存活的对象。
  • 整理:移动所有存活的对象,按照内存地址依次排列,然后将末端内存地址以后的内存全部回收。

标记-压缩算法不仅可以弥补标记-清除算法的内存碎片问题,也消除了复制算法中,额外内存空间的问题。

标记-整理算法的缺点:

效率很低,不仅要标记所有存活的对象,还要整理所有存活对象的引用地址。效率是上面两个算法中最低的。



4、标记-清除算法、复制算法、标记整理算法的总结

效率: 复制算法>标记-整理算法>标记-清除算法

内存整齐度 :复制算法=标记/整理算法>标记/清除算法。

内存利用率: 标记/整理算法=标记/清除算法>复制算法。



5、分代收集算法

概念: 根据对象的存活周期的不同,将堆内存划分为老年代和新生代。存活时间短的对象未新生代,寻获时间长的为老年代。

实践:

少量对象存活,适合复制算法,在新生代中,每次GC都会有大量对象死亡,那么就选择用复制算法。

大量对象存活,适合标记-清理\标记-压缩算法,在老年代中,对象存活率高,就用标记-清理\标记-压缩算法进行GC。



6、Stop-The_World

java中一种全局暂停的现象,全局停顿,所有代码停止,native代码可以执行,但不能和JVM交互。多半情况下时由于GC引起的。

d07bb3ea-1235-41d5-9fb1-56b4087d1acf

危害:

  • 长时间服务停止,没有响应(将用户正常工作的线程全部暂停掉)
  • 比如上面的这主机和备机:现在是主机在工作,此时如果主机正在GC造成长时间停顿,那么备机就会监测到主机没有工作,于是备机开始工作了;但是主机不工作只是暂时的,当GC结束之后,主机又开始工作了,那么这样的话,主机和备机就同时工作了。主机和备机同时工作其实是非常危险的,很有可能会导致应用程序不一致、不能提供正常的服务等,进而影响生产环境。



7、GC时为什么会有全局停顿?

1、避免无法彻底清理干净

2、GC的工作必须在一个能确保一致性的快照中进行



8、jvm调优

1、首先打印GC信息:

  • -XX:+PrintGC

2、根据不同场景设置GC的类型:

  • web接口交互的系统:使用ParNew+CMS组合,可以提高响应时间;
  • 服务型的系统:使用parallel scavenge + parallel old,可以提高吞吐量;

3、设置堆区大小:

  • -Xms:初始堆大小
  • -Xmx:最大堆大小
  • -XX:SurvivoRatio=n:设置年轻代和年老代的比值。



9、什么时候会触发GC?

  • 当新对象生成,并且在Eden申请空间失败时,就会触发Minor GC
  • 年老代(Tenured)被写满
  • 持久代(Perm)被写满
  • System.gc()被显示调用
  • 上一次GC之后Heap的各域分配策略动态变化



10、GC的类型

①年轻代垃圾回收器:

1、Serial:

单线程GC,在进行垃圾收集时,必须暂停其他所有的工作线程,直到它收集结束。

2、ParNew:

就是Serial的多线程版本,除了使用多条线程进行垃圾收集之外,其余都和Serial完全一样。老年代使用CMS时,新生代会默认使用ParNew,也只有ParNew可以和CMS配合使用。

3、Paraller Scavenge:

并行多线程收集器,server模式下默认GC的方式。停顿时间短,良好的响应速度可以提升用户体验。有自适应调节策略。


②老年代垃圾回收器:

1、Serial Old:

是Servial的老年代版本,同样是一个单线程收集器,每次进行回收都很耗时。

2、Parallel Old:

Parallel Scavenge收集器的老年代版本,多线程

3、CMS:

一种获得最短停顿时间为目标的GC,目前用重视响应速度的服务端上(如BS架构)。使用XX:+UseConcMarkSweepGC指定使用。

优点:响应时间短

缺点:对CPU资源很敏感,会导致应用变慢,总吞吐量会降低

4、G1:

并行与并发:充分利用多CPU的优势,使用多个CPU来缩短Stop-The-World停顿的时间。通过并发的形式让java程序据继续执行。

分代收集:既可以收集新生代也可以收集老年代

空间整合:采用标记-整理算法

可预测停顿:可以建立可预测的停顿时间模型,从而达到降低停顿时间的要求。


http://chatgpt.dhexx.cn/article/8Wgo7V93.shtml

相关文章

java---垃圾回收算法(GC)

目录 一、如何判断一个对象是否存活 1.引用计数法 2.可达性分析法 二、垃圾回收算法 1.标记清除法 2.复制算法 3.标记整理法 4.分代算法 具体流程 注意事项 空间分配担保原则 总结 一、如何判断一个对象是否存活 Java 堆中存放着几乎所有的对象实例,垃圾…

Java - GC 垃圾回收

JVM中一个垃圾回收线程,它的优先级较低,正常情况下不会执行。JVM空闲或者当前内存不足时,才会触发垃圾回收线程执行,扫描内没有被引用的对象,将这些对象添加到要回收的集合中进行回收。 GC介绍 Garbage Collection 垃圾收集,监测对象是否可…

GC是如何判断一个对象为垃圾的?被GC判断为垃圾的对象一定会被回收吗?

一.GC如何判断一个对象为”垃圾”的 java堆内存中存放着几乎所有的对象实例,垃圾收集器在对堆进行回收前,第一件事情就是要确定这些对象之中哪些还“存活”着,哪些已经“死去”。那么GC具体通过什么手段来判断一个对象已经”死去”的? 1.引用计数算法(…

基于28181协议的视频与平台的对接

问题描述 将IPC摄像头接入平台进行观看,或使用28181/rtsp/rtmp/flv等协议将视频流分发到其他平台。 解决方案 WVP-PRO(基于GB/T 28181-2016标准实现的流媒体平台),依托优秀的开源流媒体服务ZLMediaKit,提供完善丰富…

GB28181协议实现系列之----SDK Demo发布(7)

GB28181在终端的应用越来越广,但是一般很多做终端的厂家要加入到互联互通的GB28181网络协议栈中都必须招聘一些专业做GB28181的开发人员,并且需要对接各厂家的兼容性开发及对接调试工作,或是修改一些定制功能。安防市场一年有千亿以上的产值&…

GB28181协议之设备录像查询

目录 一、概述 二、GB28181录像文件查询 2.1 录像文件基本要求 2.2 命令流程 2.3 抓包文件抓图示例 三、国标平台介绍 一、概述 近年来,国内视频监控应用发展迅猛,系统接入规模不断扩大,涌现了大量平台提供商,平台提供商的接…

ZLMediaKit+wvp-GB28181-pro,搭建28181协议视频平台

ZLMediaKitwvp-GB28181-pro,搭建28181协议视频平台 一,简介 ZLMediaKit:实现RTSP/RTMP/HLS/HTTP协议的轻量级流媒体框架,支持大并发连接请求 一个基于C11的高性能运营级流媒体服务框架,项目地址:ZLMediaKit 特点: 基…

java gb28181网关_视频网关GB28181协议转换解决方案

原标题:视频网关GB28181协议转换解决方案 应用需求及问题: 四川某一所学校,校园内装置有上百个摄像头,学校监控系统是RTSP协议,现在需求要把校园的监控系统视频画面接入到公安系统里, 可公安系统只支持GB-T…

GB28181协议--校时

1、简介 根据《GB/T 28181 —2016》7.10、9.10的要求,GB28181设备网络校时功能描述如下: 联网系统内的IP 网络服务器设备宜支持 NTP(见IETF RFC2030) 协议的网络统一校时服务。 网络校时设备分为时钟源和客户端, 支持客户/服务器的工作模式; 时钟源应支…

GB28181协议常见几种信令流程(一)

在监控系统中,常见的摄像机设备互联协议有国际标准的ONVIF、国标的GB28181和各厂商的私有连接协议,本章从GB28181-2016中摘抄整理常见信令流程,如28181的会话/媒体通道、SIP基本注册/注销流程、客户端主动发起视频点播流程、设备控制流程等。…

国标GB28181协议客户端开发(一)整体流程和技术选型

国标GB28181协议客户端开发(一)整体流程和技术选型 本系列文章将介绍国标GB28181协议设备端的开发过程。本文旨在探讨整体设计和技术选型方面的考虑,为开发人员提供指导和参考。文章将从设备端开发的整体架构、信令交互流程以及关键技术选型等…

java gb28181网关_国标GB28181协议对接网关

国标GB28181网关概述 国标GB28181《安全防范视频监控联网系统信息传输、交换、控制技术要求》最新版为2016年版,较2011年版更加完善,其是基于SIP协议的视频联网框架标准。因其核心应用于公安视频联网,在平安城市、雪亮工程超大规模视频监控联…

GB28181协议之录像回放

目录 一、概述 二、录像文件播放 2.1 基本要求 2.2 命令流程 2.3 抓包示例 2.3.1 Invite请求[SIP服务器---->设备] 2.3.2 Invite应答[设备---->SIP服务器] 2.3.3 ACK[SIP服务器---->设备] 2.3.4 Bye结束回放 2.3.5 Bye应答 2.3.6 播放速度控制 2.3.6 控制…

GB28181协议之实时视频

目录 一、概述 二、实时视频 2.1基本要求 2.2命令流程 2.3抓包示例 2.3.1 Invite请求[SIP服务器----->设备] 2.3.2 Invite应答[设备---->SIP服务器] 2.3.3 ACK[SIP服务器----->设备] 2.3.4 Bye 2.3.5 Bye应答 三、国标平台介绍 一、概述 近年来,国…

GB28181协议--实时视音频点播(预览)

1、基本要求 根据《GB/T 28181 —2016》第9章关于实时视音频点播的描述,其内容如下: 实时视音频点播的SIP 消息应通过本域或其他域的SIP 服务器进行路由、 转发, 目标设备的实时视音频流宜通过本域内的媒体服务器进行转发。实时视音频点播采用SIP 协议…

GB28181协议--心跳

1、心跳介绍: 根据《GBT 28181-2016 公共安全视频监控联网系统信息传输、交换、控制技术要求》9.6.1状态信息报送章节描述。 当源设备(包括网关、SIP 设备、SIP 客户端或联网系统) 发现工作异常时, 应立即向本 SIP 监控域的SIP服务器发送状态信息; 无异常时, 应定…

国标28181: 视频国标28181协议

国标的由来 GB28181国标解决平台与平台对接问题 比如A平台大连交警系统需要看B平台上海交警系统的视频。需要对接过来,实现调度视频。这时候需要知道他们取流的协议,各家厂商都自定义了一套协议,就很麻烦,因此国家就制定了GB28…

【C/C++】isalpha、islower、isupper、isalnum、isblank、isspace函数cctype / ctype.h头文件

isalpha、islower、isupper、isalnum、isblank、isspace这些函数都在<cctype>&#xff08;即C语言中的<ctype.h>&#xff09;的头文件里面&#xff0c;下图是它们所表示的范围&#xff1a; 总的来说就是&#xff1a; isalpha &#xff08;字母&#xff0c;包括大写…

细微之处见真章之StringUtils的isBlank函数细节解读

一、背景 技术群里有一个老铁分享了一段 commons-lang 的 StringUtils 工具类的代码&#xff1a; public static boolean isBlank(final CharSequence cs) {int strLen;if (cs null || (strLen cs.length()) 0) {return true;}for (int i 0; i < strLen; i) {if (Char…

字符串判空,isBlank 和 isEmpty 到底选那个?

字符串的判空&#xff0c;日常开发是经常要做的一种校验&#xff0c;common-lang包帮我们做了一些字符串判空的封装 <dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId> </dependency> 并对外提…