Java 垃圾回收机制方法,判断对象存活算法

垃圾回收机制:

        不定时去堆内存中清理不可达对象。不可达的对象并不会马上就会直接回收, 垃圾收集器在一个Java程序中的执行是自动的,不能强制执行,即使程序员能明确地判断出有一块内存已经无用了,是应该回收的,程序员也不能强制垃圾收集器回收该内存块。程序员唯一能做的就是通过调用System.gc 方法来"建议"执行垃圾收集器,但其是否可以执行,什么时候执行却都是不可知的。这也是垃圾收集器的最主要的缺点。当然相对于它给程序员带来的巨大方便性而言,这个缺点是瑕不掩瑜的。

不可达对象:是指没有被继续引用,没有被继续使用,不存活的对象都是不可达对象

User user = new User()

user = null; //user 就是一个不可达对象

 

System.gc():

        用于建议垃圾回收器去回收,但是执行与否,时间都不确定

 

finalize():

        Object 对象里面的方法,finalize()方法是在垃圾收集器删除对象之前对这个对象调用的。子类覆盖此方法用于整理系统资源,或者做一些其他清理工作。

子类覆盖finalize()方法以整理系统资源或者执行其他清理工作。

 

新生代,老年代

 

 

1,java heap 可以被划分为新生代,老年代,默认比例1:2  该值可以通过参数 –XX:NewRatio 来指定

2,新生代又可以被划分为Eden区,From survivor(s0),To survivor(s1),默认的,Edem : from : to = 8 : 1 : 1 ( 可以通过参数 –XX:SurvivorRatio 来设定 )

3,绝大多数情况下,对象首先分配在eden区,在新生代回收后,如果对象还存活,则进入s0或s1区,之后每经过一次新生代回收,如果对象存活则它的年龄就加1,对象达到一定的年龄后(15),则进入老年代。

 

判断对象存活:

    引用计数法:(已经被淘汰)

         就是如果一个对象没有被任何引用指向,则可视之为垃圾。这种方法的缺点就是不能检测到环的存在。
         首先需要声明,至少主流的Java虚拟机里面都没有选用引用计数算法来管理内存。 
         什么是引用计数算法:给对象中添加一个引用计数器,每当有一个地方引用它时,计数器值加1;当引用失效时,计数器值减1.任何时刻计数器值为0的对象就是不可能再被使用的。那为什么主流的Java虚拟机里面都没有选用这种算法呢?其中最主要的原因是它很难解决对象之间相互循环引用的问题。

   根搜索算法
         根搜索算法的基本思路就是通过一系列名为”GC Roots”的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链(Reference Chain),当一个对象到GC Roots没有任何引用链相连时,则证明此对象是不可用的。
         这个算法的基本思想是通过一系列称为“GC Roots”的对象作为起始点,从这些节点向下搜索,搜索所走过的路径称为引用链,当一个对象到GC Roots没有任何引用链(即GC Roots到对象不可达)时,则证明此对象是不可用的。
        在Java语言中,可以作为GCRoots的对象包括下面几种:
       (1). 虚拟机栈(栈帧中的局部变量区,也叫做局部变量表)中引用的对象。
       (2). 方法区中的类静态属性引用的对象。
       (3). 方法区中常量引用的对象。
      (4). 本地方法栈中JNI(Native方法)引用的对象。

     通俗的说,就是看,虚拟机栈的局部变量,方法区中的静态属性,常量,还有本地方法栈里面有没有对对象有引用...

可以得出对象实例1、2、4、6都具有GC Roots可达性,也就是存活对象,不能被GC回收的对象。 
而对于对象实例3、5直接虽然连通,但并没有任何一个GC Roots与之相连,这便是GC Roots不可达的对象,这就是GC需要回收的垃圾对象。

 

posted @ 2019-07-01 21:23  Chris,Cai  阅读(557)  评论(0编辑  收藏  举报