java虚拟机(二)--垃圾收集器与内存分配策略

时间:2021-12-12 03:41:28

1、判断对象是否存活的算法:

  1.1、引用计数算法:给对象添加一个引用计数器,每当有一个地方引用他时,计数器+1,当引用失效时,计数器-1,任何时刻计数器为0的对象就是不可能再被引用的,但是他很难解决对象之间相互循环引用的问题

  1.2、可达性分析算法:该算法在主流的语言中被大量使用,该算法是通过一系列的被称为“GC Roots”的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径被称为引用链,当一个对象到GC Roots没有任何 引用链相连,则证明此对象不可用

2、java语言中的GC Roots对象

  1、虚拟机栈(栈帧中的本地变量表)中引用的对象

  2、方法区中类静态属性引用的对象

  3、方法区中常量引用的对象

  4、本地方法栈中JNI(即一般说的Native方法)引用的对象

3、java中将引用分为强引用、软引用、弱引用、虚引用

  1、强引用:是指程序代码中普遍存在的,类似“Object o=new Object()”的引用,只要强引用还存在,垃圾收集器永远不会回收被引用的对象

  2、软引用:是用来描述一些还有用但并非必需的对象,对于软引用关联的对象,在系统将要发生内存溢出异常之前,将会把这些对象列入回收范围进行第二次回收

  3、弱引用:用来描述非必需对象,他的强度比软引用更弱一些,当垃圾收集器工作时,无论当前内存是否足够,都会回收掉只被弱引用关联的对象

  4、虚引用:又被称为幽灵引用或幻影引用,他是最弱的一种引用关系,一个对象是否有虚引用的存在,不会对其生存时间构成影响,也无法通过虚引用来取得一个对象实例。

        为一个对象设置虚引用的关联的唯一目的就是能在对象被回收时收到一个系统通知

4、垃圾收集算法

  1、标记-清除算法:最基础的收集算法,后续算法都是基于这种算法进行改进,该算法分为标记和清除两个阶段,

    不足:1、效率问题,标记和清除两个过程的效率都不高。

       2、空间问题,标记清除之后会产生大量不连续的内存碎片,当在需要分配较大对象时,会因为无法找到足够的连续内存而不得不提前触发另一次垃圾回收动作

  2、复制算法:它将内存按容量划分为大小相等的两块,每次只使用一块,当这一块用完时,将还存活的对象复制到另外一块,然后把使用过的内存一次清理掉。

          内存分配时就不用再考虑内存碎片等问题,只要移动堆顶指针,按顺序分配内存即可,实现简单,运行高效。该算法的代价是将内存缩小为一半

  3、标记-整理算法:该算法的标记过程与标记-清除算法相同,后续步骤是将所有存活对象向一端移动,然后清理掉端界外的内存

  4、分代收集算法:当前商业虚拟机都采用的算法,它将java堆分为新生代和老年代,然后根据不同年代的特点采用最合适的收集算法

5、垃圾收集器

  1、Serial收集器:新生代单线程的收集器,当它进行工作时,必须暂停其它所有的工作线程

  2、ParNew收集器:Serial收集器的多线程版本

  3、Parallel Scavenge收集器:新生代多线程收集器,也是采用复制算法,他的目标是达到一个可控制的吞吐量

  4、Serial Old收集器:Serial收集器的老年代版本

  5、Parallel Old收集器:Parallel Scavenge收集器的老年代版本

  6、CMS收集器:是一种以获取最短回收停顿时间为目标的收集器,主要引用在互联网站和B/S系统的服务端

  7、G1收集器:当前收集器技术的最前沿成果