垃圾收集 Garbage Collection 通常被称为“GC”, 在jvm 中,程序计数器、虚拟机栈、本地方法栈都是随线程而生随线程而灭,栈帧随着方法的进入和退出做入栈和出栈操作,实现了自动的内存清理,因此,我们的内存垃圾回收主要集中于 java 堆和方法区中,在程序运行期间,这部分内存的分配和使用都是动态的!

@

既然是垃圾回收,那肯定要知道什么是垃圾了是吧,我相信哪一天落魄java开发宜春小哥哥去捡垃圾维持生活,哈气、一juo、弯腰、开盖、倒水,一气呵成我闭着眼,把广东靓仔没喝完的快乐肥宅水错当垃圾捡了,这广东靓仔还不得打人?是的,而JVM的垃圾收集的前提就是明确啥是垃圾!JVM首先会进行一系列计数算法判断是不是垃圾。在JVM认为是否是垃圾的评判标准为对象是否存活,对象存活就不是垃圾,不能进行回收,反之进行回收。

1、判断对象是否存活的JVM两种计数算法

判断对象是否存活的JVM两种计数算法主要有两种,分别是:引用计数、可达性分析计数算法。

一听到计数算法中有“ 算法 ”二字,小白童鞋发愣了:妈呀,数学不好,完了,不学了...咳咳咳,咋们不提算法,从咋们的日常生活开始着手,在我们平时一个东西经常没被使用,而且也用不上什么地方,那么这个东西可以说就是垃圾。其实在 Java 中也是如此,如果一个对象不可能再被引用,那么这个对象就是垃圾,应该被回收。就是这么简单粗暴,JVM两种计数算法就是这样子的,真的不复杂。

1.1、引用计数算法

根据我们生活上的思想,我们很容易想到使用引用计数的方法来判断垃圾。在一个对象被引用时加一,被去除引用时减一,这样我们就可以通过判断引用计数是否为0来判断一个对象是否为垃圾。这种方法我们一般称之为「引用计数法」。确实贼简单的一个思路也正是以为它的简单,从而存在缺陷,因此引用计数算法是这样定义的

1、引用计数:每个对象有一个引用计数属性,新增一个引用时计数加1,引用释放时计数减1,计数为0时可以回收。
2、正因方法简单,从而引用计数算法无法解决对象相互循环引用的问题

小白童鞋可能不知道啥是对象循环引用,熊dei看图

1.2、可达性分析计数算法

首先声明一点:在实际开发语言比如java、C#等都是采用可达性分析计数算法判断对象是否存活!

可达性分析算法的定义如下:

可达性分析(Reachability Analysis):从GC Roots开始向下搜索,搜索所走过的路径称为引用链。当一个对象到GC Roots没有任何引用链相连时,则证明此对象是不可用的。不可达对象。

相信很容易看出,其实都很好理解,唯独GC Roots有点抽象,那啥是GC Roots呢?在Java语言中,GC Roots主要包括:

1、对象的引用,位于虚拟机栈中。
2、方法区中的静态引用。
3、本地方法栈中JNI的引用。【JNI一般指的是Native方法】

简单地说,GC Root 就是经过精心挑选的一些引用


像上面的循环引用的这种情况引用计数算法是无法进行GC掉的,而根搜索算法可以做到,因此引用计数算法存在缺陷!根搜索算法更好!

2、垃圾收集算法

以上内容概述了啥垃圾,接下来就要讲讲如何进行回收垃圾!在生活中我们收集垃圾,可以一边走一边扫,也可以把垃圾全都扫到一起再一次清理。在JVM中,类似生活,提供了一系列的垃圾收集算法。

而且我们还经常能看到垃圾分类,分成可回收垃圾,和不可回收垃圾,但是从某一意义上来讲,还都是垃圾,如果人人都遵守垃圾分类规则,我估计以后收破烂的大叔大妈都天天从可回收垃圾桶下手了,其实在JVM中也类似如此,JVM采取了分区、分代收集的思想。

常见的垃圾回算法:标记清除算法、复制算法、标记整理算法、分代收集算法。

2.1、标记清除算法复制算法

标记清除算法。从名字可以看到其分为两个阶段:标记阶段和清除阶段。一种可行的实现方式是,在标记阶段,标记所有由 GC Root 触发的可达对象。此时,所有未被标记的对象就是垃圾对象。之后在清除阶段,清除所有未被标记的对象。标记清除算法最大的问题就是空间碎片问题。如果空间碎片过多,则会导致内存空间的不连续。虽说大对象也可以分配在不连续的空间中,但是效率要低于连续的内存空间。

2.2、复制算法(Copying)

复制(Copying)算法。复制算法的核心思想是将原有的内存空间划分为大小相等的两块,每次只使用一块,在垃圾回收时,将正在使用的内存中的存活对象复制到未使用的内存块中。之后清除正在使用的内存块中的所有对象,之后交换两个内存块的角色,完成垃圾回收。复制算法的缺点是要将内存空间折半,极大地浪费了一半内存空间。因此现在的商业虚拟机都使用这种复制算法来进行新生代的垃圾收集!因为在对象存活率高的时候,复制算法就显得效率低下

2.3、标记-整理算法(Mark-Compact)

关于标记-整理算法还有一种叫法是标记压缩算法,知道其说的同一者就好了。

标记整理算法。标记整理算法可以说是标记清除算法的优化版,其同样需要经历两个阶段,分别是:标记阶段、整理阶段。在标记阶段,从 GC Root 引用集合触发去标记所有对象,和标记清除算法中的标记阶段是一样一样的。在整理阶段,其则是将所有存活的对象整理在内存的一边,之后清理边界外的所有空间。因此,标记-整理算法(Mark-Compact)不会产生内存碎片,但是会多花点时间用在整理(Compact)上面!

2.4、分代收集算法(Generational Collection)

“分代收集”(Generational Collection)算法,把Java堆分为新生代和老年代,这样就可以根据各个年代的特点采用最适当的收集算法。在新生代中,每次垃圾收集时都发现有大批对象死去,只有少量存活,那新生代选用复制算法,只需要付出少量存活对象的复制成本就可以完成收集。而老年代中因为对象存活率高、没有额外空间对它进行分配担保,老年代就使用“标记-清理”或“标记-整理”算法来进行回收。

2.5、四种回收算法总结

标记清除算法

分为标记阶段和清除两阶段。标记清除算法最大的问题就是空间碎片问题。比较适合在存活对象比较多的情况。

复制算法(Copying)

复制算法的缺点是浪费了一半内存空间。现在的商业虚拟机都使用这种复制算法来进行新生代的垃圾收集!因为在对象存活率高的时候,复制算法就显得效率低下比较适合存活对象比较少的情况。

标记整理算法(Mark-Compact)

标记整理算法是标记清除算法的优化版,标记-整理算法(Mark-Compact)不会产生内存碎片,但是会多花点时间用在整理(Compact)上面!

分代收集算法(Generational Collection)

新生代选用复制算法老年代使用“标记-清理”或“标记-整理”算法来进行回收。

3、垃圾回收算法小结

借用大佬整理的一张图:

如果本文对你有一点点帮助,那么请点个赞呗,谢谢~

最后,若有不足或者不正之处,欢迎指正批评,感激不尽!如果有疑问欢迎留言,绝对第一时间回复!

欢迎各位关注我的公众号,里面有一些java学习资料和一大波java电子书籍,比如说周志明老师的深入java虚拟机、java编程思想、核心技术卷、大话设计模式、java并发编程实战.....都是java的圣经,不说了快上Tomcat车,咋们走!最主要的是一起探讨技术,向往技术,追求技术,说好了来了就是盆友喔...

这货到底还是不是垃圾?【垃圾回收GC算法JVM篇四】的更多相关文章

  1. JVM虚拟机垃圾回收(GC)算法及优缺点

    一.什么是GC   GC是jvm的垃圾回收,垃圾回收的规律和原则为:   次数上频繁收集新生区(Young)   次数上较少收集养老区(Old)   基本上不动永久区(Perm) 二.GC算法(分代收 ...

  2. JVM—垃圾回收GC算法

    1 GC算法简介 算法 特点 标记-清除 分为"标记"和"清除"两个阶段 复制 可以解决效率问题,将可用的内存按容量划分为大小相等的两块. 标记-整理 先标记. ...

  3. jvm-垃圾回收gc简介+jvm内存模型简介

    gc是jvm自动执行的,自动清除jvm内存垃圾,无须人为干涉,虽然方便了程序员的开发,但同时增加了开发人员对内存的不可控性. 1.jvm内存模型简介 jvm是在计算机系统上又虚拟出来的一个伪计算机系统 ...

  4. JVM学习——垃圾回收GC(学习过程)

    JVM学习-垃圾回收(GC) 2020年02月19日06:03:56,开始学习垃圾回收,学习资料来源(张龙老师的JVM课程) JVM内存数据区域知识复习 学习垃圾回收之前,要对JVM内部的内存区域有详 ...

  5. golang 垃圾回收 gc

    http://ruizeng.net/golang-gc-internals/ 摘要 在实际使用go语言的过程中,碰到了一些看似奇怪的内存占用现象,于是决定对go语言的垃圾回收模型进行一些研究.本文对 ...

  6. .NET垃圾回收(GC)原理

    作为.NET进阶内容的一部分,垃圾回收器(简称GC)是必须了解的内容.本着“通俗易懂”的原则,本文将解释CLR中垃圾回收器的工作原理. 基础知识 托管堆(Managed Heap) 先来看MSDN的解 ...

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

    GC,Garbage Collect,中文意思就是垃圾回收,指的是系统中的内存的分配和回收管理.其对系统性能的影响是不可小觑的.今天就来说一下关于GC优化的东西,这里并不着重说概念和理论,主要说一些实 ...

  8. 垃圾回收GC:.Net自己主动内存管理 上(一)内存分配

    垃圾回收GC:.Net自己主动内存管理 上(一)内存分配 垃圾回收GC:.Net自己主动内存管理 上(一)内存分配 垃圾回收GC:.Net自己主动内存管理 上(二)内存算法 垃圾回收GC:.Net自己 ...

  9. Java 类加载机制 ClassLoader Class.forName 内存管理 垃圾回收GC

    [转载] :http://my.oschina.net/rouchongzi/blog/171046 Java之类加载机制 类加载是Java程序运行的第一步,研究类的加载有助于了解JVM执行过程,并指 ...

随机推荐

  1. 1、Hibernate-入门

    一.概述 1.什么是Hibernate: Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,它将POJO与数据库表建立映射关系,是一个全自动的orm框架,h ...

  2. nginx篇最初级用法之nginx升级

    在不破坏nginx应用程序和配置文件下时,升级nginx. 下载新版本的nginx对其进行编译 使用nginx -V参数获得当前版本和配置参数 nginx version: nginx/1.10.3b ...

  3. 最新开源JavaScript 图表库 ECharts推荐

    ECharts是一款由百度前端技术部开发的,基于Javascript的数据可视化图表库,提供直观,生动,可交互,可个性化定制的数据可视化图表. ECharts 提供大量常用的数据可视化图表,底层基于Z ...

  4. table的列固定

    <body onload="showFix(true,false,initTableId);"> <!doctype html> <html lang ...

  5. C++中对C的扩展学习新增语法——const

     Const Const在C语言和C++语言中连接属性不一样,C语言默认是外部连接,如果需要内部连接,需要显示写上static.而在C++中默认是内部连接,如果希望其编程外部变量,需要显示写上exte ...

  6. VS安装

    1. 只更改工作负载和单个组件 工作负载:我只勾选3个需要的 单个组件:  勾选  .NET 下Framework   别的不用改 2.点击安装,安装完成重启

  7. 后台服务器框架中的瑞士军刀——MCP

    上篇介绍了一个简单的UDP服务框架,但是面对海量的请求,同步框架显然有点力不从心.于是在我接手好友系统的接口服务的时候,就采用了一个强大的异步框架——MCP框架. MCP框架是一个多进程异步框架,支持 ...

  8. nyoj 96-n-1位数 (strlen, atoi, ceil)

    96-n-1位数 内存限制:64MB 时间限制:3000ms 特判: No 通过数:30 提交数:47 难度:1 题目描述: 已知w是一个大于10但不大于1000000的无符号整数,若w是n(n≥2) ...

  9. ArcGIS API For Javascript :读取 CSV 文件的方法

    我们临时会遇到一些测试数据,通常从数据库中以 CSV 格式导出.最简单实用的方法就是使用 ajax 去读取文件,记得引入 jQuery . 例如,在<ArcGIS JS API :新增一个热力图 ...

  10. raid10配置流程(5块磁盘)

    1.添加5块磁盘 (1)先添加一块磁盘 (2)在此基础上,再添加4块磁盘 2.使用mdadm命令创建RAID10,名称为“/dev/md0” -C 代表创建操作      -v 显示创建过程      ...