一、概述

GC(Carbage Collection)垃圾收集器,由JVM自动回收已死亡的对象垃圾。

这也是Java与C++等语言的主要区别之一。

二、如何确认对象已死

1. 引用计数算法

引用计数法实现简单,效率较高,在大部分情况下是一个不错的算法。

其原理是:给对象添加一个引用计数器,每当有一个地方引用该对象时,计数器加1,当引用失效时,计数器减1,

当计数器值为0时表示该对象不再被使用。

需要注意的是:引用计数法很难解决对象之间相互循环引用的问题,主流Java虚拟机没有选用引用计数法来管理内存。

 public class ReferenceCountingGC {
public Object instance = null;
private static final int ONE_MB = 1024 * 1024; private byte[] bigSize = new byte[2 * ONE_MB]; public static void main(String[] args) {
testGC();
}
public static void testGC() {
ReferenceCountingGC objA = new ReferenceCountingGC();
ReferenceCountingGC objB = new ReferenceCountingGC();
objA.instance = objB;
objB.instance = objA; objA = null;
objB = null; System.gc();
}
}

2. 可达性分析算法

主流语言(Java、C#)等都是通过可达性分析算法来判断对象是否存活。

这个算法的基本思路就是通过一系列的称为“GC Roots”的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链,

当一个对象到GC Roots没有任何引用链相连(用图论的话来说,就是从GC Roots到这个对象不可达)时,则证明此对象是不可用的。

如图所示,对象object 5、object 6、object 7虽然互相有关联,但是它们到GC Roots是不可达的,所以它们将会被判定为是可回收的对象。

三、垃圾收集算法

1. 标记-清除算法

标记-清除算法分为两个阶段:标记阶段和清除阶段。

  • 标记阶段的任务是标记出所有需要被回收的对象。
  • 清除阶段就是回收被标记的对象所占用的空间。

缺点:

  • 标记和清除两个过程效率不高
  • 容易产生内存碎片,碎片太多可能会导致后续过程中需要为大对象分配空间时无法找到足够的空间而提前触发新的一次垃圾收集动作。

2. 复制算法(用于新生代)

为了解决效率问题,提出来复制算法。它将可用内存按容量划分为大小相等的两块,每次只使用其中的一块。

当这一块的内存用完了,就将还存活着的对象复制到另外一块上面,然后再把已使用的内存空间一次清理掉,内存分配时,就不需要考虑内存碎片等问题,

只要移动堆顶指针,按顺序分配内存。实现简单、运行高效。适用于移动较少的情况。

缺点:

  • 能够使用的内存缩减到原来的一半。
  • 如果存活对象很多,需要很多复制操作,Copying算法的效率将会大大降低。

3. 标记-整理算法(用于老年代)

在完成标记之后,它不是直接清理可回收对象,而是将存活对象都向一端移动(记住是完成标记之后,先不清理,先移动再清理回收对象),然后清理掉端边界以外的内存。

4. 分代收集算法

分代收集算法是目前大部分JVM的垃圾收集器采用的算法。

核心思想是根据对象存活的生命周期将堆区划分为新生代和老年代。

新生代每次垃圾收集时,都有大批对象死去,所以用复制算法。

老年代对象存活率较高,使用“标记-清除”算法或者“标记-整理“算法。

新生代和老年代的区别:

将新生代划分为一块较大的Eden空间和两块较小的Survivor空间(一般为8:1:1),每次使用Eden空间和其中的一块Survivor空间,

数据会首先分配到Eden区 当中,当Eden没有足够空间的时候就会 触发jvm发起一次Minor GC。如果对象经过一次Minor GC还存活,

并且又能被Survivor空间接受,那么将被移动到Survivor空 间当中。并将其年龄设为1。

反复将Eden和Survivor中还存活的对象复制到另一块Survivor空间中,然后清理掉Eden和刚才使用过的Survivor空间。

对象每熬过一次Minor GC,年龄就加1,

当年龄达到一定的程度(默认为15)时,就会被晋升到老年代 中了,晋升老年代的年龄是可以设置的。如果老年代满了就执行:Full GC 。

深入理解Java GC的更多相关文章

  1. 深入理解 Java —— GC 机制

    1. 基础知识 1.1 什么是垃圾回收? 程序的运行必然需要申请内存资源,无效的对象资源如果不及时处理就会一直占有内存资源,最终将导致内存溢出,所以对内存资源的管理非常重要. 垃圾回收就是对这些无效资 ...

  2. 理解Java GC日志

    idea 在vm options处加入-XX:+PrintGCDetails,可打印GC日志. public class ReferenceCountingGC { public Object ins ...

  3. Java GC回收机制

    优秀Java程序员必须了解的GC工作原理 一个优秀的Java程序员必须了解GC的工作原理.如何优化GC的性能.如何与GC进行有限的交互,因为有一些应用程序对性能要求较高,例如嵌入式系统.实时系统等,只 ...

  4. jvm系列(十):如何优化Java GC「译」

    本文由CrowHawk翻译,是Java GC调优的经典佳作. 本文翻译自Sangmin Lee发表在Cubrid上的"Become a Java GC Expert"系列文章的第三 ...

  5. 深入理解JAVA虚拟机JVM

    深入理解JAVA虚拟机JVM Java 虚拟机(Java virtual machine,JVM)是运行 Java 程序必不可少的机制.java之所以能实现一次编写到处执行,也就是因为jVM.原理:编 ...

  6. jvm系列(七):如何优化Java GC「译」

    本文由CrowHawk翻译,地址:如何优化Java GC「译」,是Java GC调优的经典佳作. Sangmin Lee发表在Cubrid上的”Become a Java GC Expert”系列文章 ...

  7. jvm系列(十):如何优化Java GC「

    转自:https://www.cnblogs.com/ityouknow/p/7653129.html 本文由CrowHawk翻译,地址:如何优化Java GC「译」,是Java GC调优的经典佳作. ...

  8. 深入理解java:1.3.1 JVM内存区域的划分(运行时数据区)

    学习Java GC机制,可以帮助我们在日常工作中 排查各种内存溢出或泄露问题,解决性能瓶颈,达到更高的并发量,写出更高效的程序. 我们将从4个方面学习Java GC机制, 1,内存是如何分配的: 2, ...

  9. Java GC(垃圾回收)机制知识总结

    目录 Java GC系列 Java关键术语 Java HotSpot 虚拟机 JVM体系结构 Java堆内存 启动Java垃圾回收 Java垃圾回收过程 垃圾回收中实例的终结 对象什么时候符合垃圾回收 ...

随机推荐

  1. sass(scss)10大常用重要特性

    用sass用了好久,期初看中的是他的嵌套功能,因为刚开始的时候是用jquery,电脑安装Ruby,全局安装sass,将scss编译为css,不得不说真的很方面,节点套节点,和html的很类似.但是后来 ...

  2. 今天实现一个T-sql的小编程,分享给大家,看看就好~(列值赋值)

    介绍:将一个表的某列值插入到另一个表的列里,暂定为表aa和表nn DECLARE @a int set @a=1 while @a<nn.列1.length    --(注:语法不对你可以用查询 ...

  3. PHP Redis锁

    一.什么是 Redis Redis是由意大利人Salvatore Sanfilippo(网名:antirez)开发的一款内存高速缓存数据库 二.什么是 Redis 分布式锁 分布式锁其实可以理解为:控 ...

  4. vbox安装64位ubuntu

    如果不做任何设置的话,你会发现下载下来的vbox只能安装32位的系统,如果想要安装64位的系统,我们需要做一些配置: 进入bios(basic input output system), Securi ...

  5. java 核心技术 读后总结

    总结 1.少用八进制,以及二进制. 那么就是直接用16进制或10进制吗?额,想当年有这样搞过,后面就uuid了. 2.>>>用0填充高位>>用符号位填充高位<< ...

  6. input累加赋值

    需求如下:第一个input添加字符到第二个input,第二个input需要累加. html: <tr> <td rowspan="2" class="D ...

  7. 10.&与&&以及位运算符。

    这是单独的一块,因为一条讲不清楚(虽然内容也不够一篇),而且我之前也没好好弄清楚,所以有必要写出来. 说位运算符也是从&与&&(|与||类似)之间的区别讲起的.事实上,对于两个 ...

  8. springMvc 添加定时任务

    1.创建定时类 import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stere ...

  9. A promise tomorrow is worth a lot less than trying today.

    A promise tomorrow is worth a lot less than trying today.明日的承诺远不及今日的行动.

  10. <Android 基础(五)> MVVM

    介绍 MVVM,Model-View-ViewModel,与上次讲的MVP模式比较的类似,MVP中需要大量的接口文件,而MVVM模式下,View和ViewModel直接关联,使用上比较方便,简化了代码 ...