美文网首页
JAVA GC算法简介

JAVA GC算法简介

作者: LibraLIn | 来源:发表于2020-11-09 20:58 被阅读0次

    GC是java语言对回收不在继续使用的内存空间进行回收的程序流程的一个简介。

    所以说GC 总共需要做以下的几件事情:

    1.首先需要确认哪些内存需要被回收

    2.回收的时候应用程序是否可以承担这次操作

    3.回收之后的内存 如何在应用到程序中

    1.首先我们需要判断哪些内存需要被回收

    目前大家应该理解java里对象的概念,如果说一个对象创建后,程序运行时,对象并没有被使用,或者之前被使用,但是运行一段时间之后,对象没有被使用。

    这样就代表这这个对象是应该被回收的一个状态。

    下面咱们看一下java是如何判断这个对象有没有被使用的

    1.引用计数法,编译时候 如果当前对象有引用的情况下 就给当前对象的引用计数器+1

    当引用执行过后 将计数器-1;

    当计数器为0的时候 java会判断当前对象是死亡状态,当前对象占用的内存可以被回收。

    (但是 目前主流的GC都已经不再使用此算法,简单来说 如果俩个对象相互引用,那就会造成俩个对象的引用永远都为1,不会被回收)

    2.可达性算法   利用树的概念 每一个对象都是一个节点,如果有节点链接不到这树上之后,当前节点 就会被回收。

    此图是知乎上一个回答盗用的,https://www.zhihu.com/question/21539353

    从当前图中 我们可以看到 实例三和实例五 是可以被回收的,因为对于GCRoots来说 他们并不可达。


    2.当那些被java虚拟机认定已经死亡的对象,并不会立马被回收,什么时候会回收这些内存?

      如果对象复写了finalize(),当前对象会被加载到finalize F-Queue中

      没有复写的话 就是直接被回收,



    3.回收内存的算法(这里暂时不详细介绍这几种算法的实现,简单介绍下实现过程)

    1、标记 清除算法

    其实就是如果说不可达的内存就会被直接回收,然后每次都需要遍历一次,而且会产生大量的内存碎片(因为有些连续内存区的对象,有些被标记 有些被回收,如果想要一片连续的内存,就没有办法在这片内存区申请)

    2.复制算法 

    其实就相当于是一种上述算法的优化 去解决连续内存的问题,实现方式比较简单,就是将现在正在使用的内存 开辟一个跟使用内存大小一样的区域,然后将所有可达的内存区域都复制到新开辟的区域,剩下之前的区域全部回收。

    3.标记整理算法

    这个其实就是一片连续的内存区域,将所有存活的对象都向左或向右移动,这样一侧的对象都是存活的 另一侧 都是空闲下来的内存,相较于复制来说  内存相对规整,不需要复制

    但是效率不如复制算法。


    现代商业虚拟机会将java堆分成新生代和老年代,老年代的对象大部分都是长期存活的对象采取标记整理算法,然后新生代对象 大部分都采取复制算法 ,因为新生代对象大部分存活时间比较短,每次会腾出很多新的空间。

    相关文章

      网友评论

          本文标题:JAVA GC算法简介

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