垃圾收集器与内存分配策略---确定对象的存亡状态

概述

  垃圾收集主要是针对方法区两部分内存,程序计数器和Java虚拟机栈,还有本地方法栈,都随着线程的存在而存在,随着线程的消亡而消亡,因此不需要对这三个部分进行垃圾收集。

确定对象的存亡状态

(1)引用计数算法

  给对象添加一个引用计数器,每当有一个地方引用它,计数器就加一,当引用失效时,计数器的值就减一,任何时刻计数器值为0 的对象就是不能再使用的对象

​ 客观的说这种算法实现简单,判定效率也比较高,但是大多数虚拟机没有选用这种算法来管理内存,其中最主要的原因就是,它没法解决相互循环引用的问题

public class Test{
    public Object instance=null;
    public static void main(String[]args){
        Test A=new Test();
        Test B=new Test();
        A.instance=B;
        B.instance=A;
    }
}

(2)可达性分析算法

  在主流的商用程序中的主流方法都是通过可达性分析算法来判断一个对象是否存活的。这个算法就是通过一系列的GC Roots的对象作为起点,从这些节点向下进行搜索,搜索经过的路径称为引用链当一个对象到达GC Roots没有任何引用链相连时,则证明该对象是不可用的

  Java语言中GC Roots的对象包含以下几种:

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

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

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

  4.本地方法栈引用的对象。

(3)引用

  无论是通过引用计数算法判断对象是否存活,还是通过可达性分析算法判断对象的引用链是否可达,判定对象的存活与否都与“引用”有关。

  Java的引用分为强引用软引用弱引用虚引用四种,这四种的引用强度依次逐渐减弱。

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

Object obj = new Object();

  软引用描述有用但非必须的对象,对于软引用关联的对象,在内存溢出之前,将会将这些对象列入被回收的范围之中,进行第二次回收

Object obj = new Object();
SoftReference<Object> sf = new SoftReference<Object>(obj);
obj = null;  // 使对象只被软引用关联

  弱引用描述非必须对象,被弱引用关联的对象,只能生存到下次垃圾收集发生之前

  虚引用的唯一目的是在对象被收集的时候会收到系统通知

Object obj = new Object();
WeakReference<Object> wf = new WeakReference<Object>(obj);
obj = null;

(4)finalize()

  当一个对象可被回收时,如果需要执行该对象的 finalize() 方法,那么就有可能在该方法中让对象重新被引用,从而实现自救自救只能进行一次,如果回收的对象之前调用了 finalize() 方法自救,后面回收时不会再调用该方法。

(5)回收方法区

  方法区的垃圾回收主要两部分:废弃常量无用的类

  无用的类满足三个条件:

  (1)该类的所有实例都已经被回收

  (2)加载该类的ClassLoader已经被回收。

  (3)该类对应的java.lang.Class对象没有在任何地方被引用,无法再任何地方通过反射访问该类的方法。

posted @ 2019-04-12 12:54  yjxyy  阅读(147)  评论(0编辑  收藏  举报