【JAVA进阶架构师指南】之四:垃圾回收GC

前言

??在【JAVA进阶架构师指南】系列二和三中,我们了解了JVM的内存模型以及类加载机制,其中在内存模型中,我们说到,从线程角度来说,JVM分为线程私有的区域(虚拟机栈/本地方法栈/程序计数器)和线程公有区域(方法区和java堆),其中线程私有区域内存随着线程的结束而跟着被回收,GC主要关注的是堆和方法区这部分的内存.

GC回收算法

??GC如何确定哪些对象需要回收呢?一般而言,有两种算法:引用计数算法和可达性分析算法.

引用计数算法

??为每个对象都持有一个引用计数器,初试状态为0,该对象每次被引用就加一,否则就减一,因此当GC进行垃圾回收的时候,判断如果该引用计数器=0则进行回收,否则不进行回收,显而易见,引用计数算法的缺点就是不能解决循环依赖的问题,假如对象A引用对象B,对象B引用对象C,对象C引用对象A,循环依赖导致ABC三个对象都不能被回收.因此引出了可达性分析算法.

可达性分析算法

??所谓可达性分析算法,就是通过一系列名为"GC Roots"的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链(Reference Chain),当一个对象到GC Roots没有任何引用链相连时,则证明此对象是可以被回收的,反之则不可被回收,在JAVA中,可被作为"GC Roots"的对象包括如下几种:

??a.虚拟机栈(栈桢中的本地变量表)中的引用的对象

??b.方法区中的类静态属性引用的对象

??c.方法区中的常量引用的对象

??d.本地方法栈中JNI的引用的对象

java语言对象引用类型

??无论是引用计数算法还是可达性分析算法,都涉及到对象的引用,在Java中,引用分为强引用、软引用、弱引用、虚引用(幽灵引用)4种,这四种引用强度依次逐渐减弱.所谓强引用,就是我们平时最常用的new一个新对象,比如:

	Object object = new Object();

强引用的对象永远不会被GC回收,即使在内存不足的情况下,JVM宁愿抛出OutOfMemory错误也不会回收这种对象,因此,我们看许多优秀框架的源码的时候,经常会看到如下代码:

??后面有注释//help gc, 将对象置为null,帮助GC进行垃圾回收,这里就是消除强引用,让无用对象的内存能被顺利回收.有兴趣的童鞋可以多多翻看优秀框架的源码,比如JDK/Spring中肯定会有大量这样的写法,足见这些源码作者的态度之严谨,编程功力之深厚,值得我们学习!

??而软引用、弱引用、虚引用这几类在JDK中都有对应的实现,分别对应SoftReference/WeakReference/PhantomReference,由于博客篇幅有限,不能所有知识点都讲得很详细,只能告诉童鞋们有这些知识点,有兴趣的童鞋可以自己下去学习了解.

GC回收策略

??讲完了GC如何确定哪些对象需要回收之后,我们再来看看GC进行垃圾回收有哪些策略,一般而言,有三种:标记清除算法/复制算法/标记整理算法.

1.标记清除算法

??标记清除算法是最基础的回收算法,分为标记和清除两个部分:首先标记出所有需要回收的对象,这一过程在可达性分析过程中进行.在标记完之后统一回收所有被标记的对象:

??这种算法的缺点很明显,就是会产生大量不连续的内存碎片,导致经常无法分配出较大的内存,从而不得不经常触发垃圾回收.

2.复制算法

??既然不能回收出连续的内存空间,那就从一开始就把内存划分为两个区,平时只用一个区域,当其中一个区域内存满了,触发GC时,找出无需回收的对象,将它们全部转移到另一块未使用的区域,并且整理到一起使之连续,如此循环,这就是复制算法:

复制算法改善了标记清楚算法中内存碎片不连续的缺点,但是它的缺点也很明显,内存利用率不高,每次只能使用50%的内存.

3.标记整理算法

??既然复制算法每次只能使用一半的内存,内存使用率不高,那就再继续优化,还是和标记清楚算法一样使用全部区域的内存,不同于标记清除算法的是进行垃圾回收时,确认无需回收的对象,然后将这些对象进行整理后向一端移动:

标记整理算法的优点在于内存使用率更充分,并且不会产生大量内存碎片.

堆(Heap)中的回收算法

??java堆采用分代搜集来进行垃圾回收.首先明确一点,堆中为什么要进行分代?或者说,java堆为什么要使用分代收集算法来进行垃圾回收?因为据权威统计,80%以上的对象都是朝生夕死,即这些对象随着方法的执行完毕而不再使用,可以被回收,而剩余的20%左右的对象是还需要继续被使用,无法回收的,因此,JDK根据对象的这种特点进行分代收集,一句话概括就是对象的生命周期不同.

??所谓分代收集,就是把java堆分为新生代和老年代,老年代采用标记整理算法,而新生代采用复制算法,其中将新生代划分为伊甸园区(Eden)和幸存区(Survivor)S0以及S1(有的也称之为Survivor from和Survivor to),默认情况下其比例为8:1:1,而整个新生代和老年代的比例为1:2(即新生代占整个堆区1/3,而老年代占2/3):

??至于新生代和老年代的详细工作流程,就不再赘述,网上这种博客太多了.需要注意的是,发生在新生代的GC称之为Minor GC或者 Young GC,而发生在老年代的GC称之为Full GC或者Major GC,一般而言,Full GC的效率会比Minor GC低十倍以上!

??读完本篇文章,我相信童鞋们应该对JVM垃圾回收有了一定的了解,下一篇文章,让我们来学习一下JVM篇最后一个知识点,也是最重要的知识点---JVM性能调优,敬请期待!

??如果觉得博主写的不错,欢迎关注博主微信公众号,博主会不定期分享技术干货!

本文由博客一文多发平台 OpenWrite 发布!

原文地址:https://www.cnblogs.com/wukongbubai/p/12683510.html

时间: 2024-09-29 16:40:04

【JAVA进阶架构师指南】之四:垃圾回收GC的相关文章

【JAVA进阶架构师指南】之一:如何进行架构设计

前言 ??本博客是长篇系列博客,旨在帮助想提升自己,突破技术瓶颈,但又苦于不知道如何进行系统学习从而提升自己的童鞋.笔者假设读者具有3-5年开发经验,java基础扎实,想突破自己的技术瓶颈,成为一位优秀的架构师,所谓java基础扎实,比如: ??1.java语言三大特性. ??2.java语言八大基本类型及其表示范围. ??3.为什么float和double存在精度丢失? ??4.publish/private/default/protected表示的范围? ??5.static/final的用

Java进阶之内存管理与垃圾回收

Java是在JVM所虚拟出的内存环境中运行的.内存分为栈(stack)和堆(heap)两部分.我们将分别考察这两个区域. 栈 在Java中,JVM中的栈记录了线程的方法调用.每个线程拥有一个栈.在某个线程的运行过程中,如果有新的方法调用,那么该线程对应的栈就会增加一个存储单元,即帧(frame).在frame中,保存有该方法调用的参数.局部变量和返回地址. 调用栈 Java的参数和局部变量只能是基本类型的变量(比如int),或者对象的引用(reference).因此,在栈中,只保存有基本类型的变

15套java互联网架构师、高并发、集群、负载均衡、高可用、数据库设计、缓存、性能优化、大型分布式 项目实战视频教程

* { font-family: "Microsoft YaHei" !important } h1 { color: #FF0 } 15套java架构师.集群.高可用.高可扩 展.高性能.高并发.性能优化.Spring boot.Redis.ActiveMQ.Nginx.Mycat.Netty.Jvm大型分布 式项目实战视频教程 视频课程包含: 高级Java架构师包含:Spring boot.Spring  cloud.Dubbo.Redis.ActiveMQ.Nginx.Mycat

Java 垃圾回收(GC) 泛读

Java 垃圾回收(GC) 泛读 文章地址:https://segmentfault.com/a/1190000008922319 0. 序言 带着问题去看待 垃圾回收(GC) 会比较好,一般来说主要的疑惑在于这么几点: 为什么需要 GC ? 虚拟机(JVM) 与 垃圾回收(GC) 的关系? GC 的原理有哪些? 哪些 对象容易被 GC ? 等等 带着这些问题往下看: 1. 为什么需要 GC ? GC: 是Garbage Collection 的英文缩略,垃圾收集的意思. 为什么需要 GC?主要

(转)《深入理解java虚拟机》学习笔记3——垃圾回收算法

Java虚拟机的内存区域中,程序计数器.虚拟机栈和本地方法栈三个区域是线程私有的,随线程生而生,随线程灭而灭:栈中的栈帧随着方法的进入和退出而进行入栈和出栈操作,每个栈帧中分配多少内存基本上是在类结构确定下来时就已知的,因此这三个区域的内存分配和回收都具有确定性.垃圾回收重点关注的是堆和方法区部分的内存. 常用的垃圾回收算法有: (1).引用计数算法: 给对象中添加一个引用计数器,每当有一个地方引用它时,计数器值就加1:当引用失效时,计数器值就减1:任何时刻计数器都为0的对象就是不再被使用的,垃

怎么成为java高级架构师?图灵学院总结的java架构师学习路线

怎么成为一个java高级架构师呢?相信这是很多java从业者,又或者说是coder/码农们比较感兴趣的问题,要回答这个问题,首先需要明白的是java架构师是什么?简单点说,架构师的主要任务不是从事具体的软件程序的编写,而是从事更高层次的开发构架工作.主要着眼于系统的"技术实现",工作内容就是确认和评估系统需求,给出开发规范,搭建系统实现的核心构架,并澄清技术细节.扫清主要难点的技术人员,并且需要有良好的组织管理能力.因此应该是特定的开发平台.语言.工具的大师,对常见应用场景能马上给出最

.NET 收徒,带你进阶架构师思维

最近感悟天命,偶有所得,故而打算收徒若干,以继吾之传承. 有缘者,可破瓶颈,领悟架构师思维,职场巅峰指日可待. 入门基本要求: 1.工作经验:1年或以上. 2.拜师费用:2999元(RMB). 联系方式: 博客:https://www.cnblogs.com/letyouknowdotnet/ 扫码联系我,备注:.NET拜师 传承说明: 1.报名截止:随时. 2.指导:3个月. 3.出师:以.NET框架系统传授架构思想,进阶架构师思维,提高职场竞争力. .NET框架系统(Window负载均衡架构

从C#垃圾回收(GC)机制中挖掘性能优化方案

GC,Garbage Collect,中文意思就是垃圾回收,指的是系统中的内存的分配和回收管理.其对系统性能的影响是不可小觑的.今天就来说一下关于GC优化的东西,这里并不着重说概念和理论,主要说一些实用的东西.关于概念和理论这里只做简单说明,具体的大家可以看微软官方文档. 一.什么是GC                                                                                              GC如其名,就是垃圾收集

性能测试三十五:jvm垃圾回收-GC

垃圾回收-GC 三个问题 哪些内存需要回收? 什么时候回收? 如何回收? YoungGC和FullGC: 新生代引发的GC叫YoungGC 老年代引发的GC叫FullGC FullGC会引起整个Jvm的用户线程暂停,待垃圾回收完毕后,才继续运行 引用的定义:如果reference类型的数据中存储的数值代表的是另外一块内存的起始地址,就称这块内存代表一个引用 对象存活状态: 确定对象"存活"还是"死去":以下两种算法原理都一样,就是看当前这个对象,是否有引用正在指向它