美文网首页
GC浅谈(一)

GC浅谈(一)

作者: guqj | 来源:发表于2017-07-23 12:09 被阅读0次

人所缺乏的不是才干而是志向,不是成功的能力而是勤劳的意志。-部尔卫

Java语言的一大特点就是可以进行自动垃圾回收处理,而无需开发人员过于关注系统资源的释放,大大减轻了开发人员的工作量,但同时也增加了软件系统的负担。
  垃圾收集器要解决的问题是:

  • 哪些对象需要回收
  • 何时回收这些对象
  • 如何回收这些对象

1. 判断对象可被回收的几种算法

在JVM堆内存中存放着JAVA程序几乎所有的对象实例,垃圾收集器在对堆内存进行回收前,首先要确定的是哪些对象是需要被回收的。

1.1 引用计数算法

引用计数法是最经典也是最古老的一种垃圾收集方法。
  引用计数器的实现很简单,对于一个对象A,只要有任何一个对象引用了A,则A的引用计数器加1,当不再引用时,则减1.若对象A的引用计数器的值为0,则对象可被回收。
  该方法存在一个问题,无法处理循环引用的情况。如对象A和对象B,对象A中存在对象B的引用,对象B中存在对象A的引用,两个对象的引用计数器都不为0,但却不存在第三个对象引用了A或B。这种情况下,对象A和B是应该被回收的,但由于引用计数器不为0.垃圾收集器却不能将内存回收,引起内存泄漏。
  由于无法处理循环引用的问题,引用计数法不适用于JVM的垃圾回收。

1.2 可达性分析算法

这个算法就是通过"GC Roots"的对象作为起始点,从这些点向下搜索,搜索走过的路径称为引用链,若某个对象到GC Roots没有任何引用链时,则该对象时不可用的,将会被判断为可回收的对象。如下图所示:

判断对象是否可被回收

可作为GC Roots的对象包含下面几种:
  (1) 虚拟机栈(栈帧中的本地变量表)中引用的对象
  (2) 方法区中类静态属性引用的对象
  (3) 方法区中常量引用的对象
  (4) 本地方法栈(即native)引用的对象

2. 垃圾收集算法

2.1 标记-清除算法

标记-清除算法将垃圾回收分为两个阶段:标记阶段和清除阶段。标记-清除算法先通过根节点(GC Roots)标记所有可达对象,然后清除所有未被标记的对象,完成垃圾回收。标记-清除算法可能产生最大的问题就是空间碎片(即内存空间不连续)。如下图所示:

标记-清除算法

2.2 复制算法

复制算法的核心思想是:将内存空间分为两块,每次只使用其中的一块,在垃圾回收时,将正在使用的内存中的存活对象复制到未使用的内存块中,再清除正在使用的内存中的所有对象。该算法可确定回收后的内存空间没有碎片,但是缺点是系统内存折半。如下图所示:

复制算法

在JVM的新生代串行收集器中,使用了复制算法。新生代分为eden、from、to三个部分。其中from和to是用于复制的两块大小相同的内存块,用于存放未被回收的对象。

适用复制算法的前提是存活对象少,垃圾对象多的内存空间。

2.3 标记-压缩算法

标记-压缩算法是老年代的回收算法,分为标记和压缩两个阶段。标记阶段从根节点开始,对所有可达对象做一次标记,压缩阶段是将所有存活对象压缩到内存的一端,然后清理边界所有的空间。这种方法同样也避免产生空间碎片。如下图所示:

标记-压缩

2.4 增量算法

对于大部分垃圾回收算法而言,在垃圾回收过程中,程序将处于一种Stop the world的状态。在Stop the world状态下,程序所有的线程将被挂起,等待垃圾回收的完成。如果垃圾回收时间过长,应用程序将会被挂起很久。
  增量算法的思想是:让垃圾收集线程和应用程序线程交替执行。垃圾收集线程只收集一小片区域的内存空间,接着切换到应用程序线程,以此反复,直至垃圾回收完成。使用这种方式,能减少系统的停顿时间,但是,因为线程切换和上下文转换的消耗,使得垃圾回收成本上升,造成系统吞吐量下降。

2.5 分代算法

分代算法的思想是:根据内存空间的特点,使用合适的回收算法,以提高垃圾回收的效率。
  以HotSpot为例,新生代因为存活对象少,垃圾对象多,使用复制算法,效率会很高。老年代存活对象多,垃圾对象少,因此适用标记-压缩算法,以提高回收效率。

相关文章

  • GC浅谈(一)

    人所缺乏的不是才干而是志向,不是成功的能力而是勤劳的意志。-部尔卫 Java语言的一大特点就是可以进行自动垃圾回收...

  • 浅谈GC

    为什么要了解GC 对于Java程序猿来说,内存分配与释放都交给JVM处理,而更多的精力能够投入到业务开发中去,这也...

  • GC浅谈(二)

    最糟糕的是人们在生活中经常受到错误志向的阻碍而不自知,真到摆脱了那些阻碍时才能明白过来。 —— 歌德 1. 对象的...

  • GC浅谈(三)

    人生并不像火车要通过每个站似的经过每一个生活阶段。人生总是直向前行走,从不留下什么。 —— 刘易斯 GC日志理解 ...

  • 浅谈GC机制

    一、什么是GC 在Java中,对象所占用的内存在对象不再使用后会自动被回收。这些工作是由一个叫垃圾回收器 Garb...

  • golang GC浅谈

    GC 回到正题:什么是GC?为什么需要GC,说到这个问题之前,需要了解的是相对底层语言:C++、C都是可以直接和操...

  • Java 垃圾收集(GC)浅谈

    Java 垃圾收集(GC)浅谈 为什么需要垃圾回收?哪些内存需要回收?什么时候回收?如何回收? 为什么需要垃圾回收...

  • 内存优化(三)Android对象池使用

    概述 由内存优化(一)浅谈内存优化中看出,内存优化不仅要从防止内存泄露入手,也要注意频繁GC卡顿,内存抖动以及不必...

  • JAVA教程:浅谈JVM的优化

    浅谈JVM的优化 前言 前面我们了解过JVM中堆的GC分代回收机制,在运行Java程序时,我们可以使用JVM的参数...

  • 浅谈GC垃圾回收机制

    首先,说一下为什么要进行GC垃圾回收手机内存给每个因公分配的内存都是有限的,如果频繁创建对象,而没有对无用对象进行...

网友评论

      本文标题:GC浅谈(一)

      本文链接:https://www.haomeiwen.com/subject/ichkkxtx.html