gc的对象的分类

Gc对象的性质

 

可触及

我们都知道,gc对无用对象进行标记,然后回收。

我们需要了解一下,gc是如何识别到这个对象是无用对象的?

 gc的对象的分类

 

从根节点有链条链到这个对象,我们就说这个对象是可触及的,可触及的对象就不应该被回收。

可复活

虽然现阶段不可触及,但是后面有可能再次被标记为可触及。

 

 gc的对象的分类

 

不可触及

不可触及对象就可回收了,不可触及的对象再也不可能被标记成可触及了。

 

 

 gc的对象的分类

 

 

使用finalize方法来复活对象

 gc的对象的分类

 

 gc的对象的分类gc的对象的分类

 

使用finalize的问题:

1. 如果使用finalize复活之后,忘记进行置null,那么虚拟机是否会回收这个被复活的对象呢?

2. 因为finalizegc的时候发生的,gc的发生是虚拟机调用的,调用的时候存在不确定性,finalize何时被调用是不知道的。

 gc的对象的分类

根的引用链。

 gc的对象的分类

栈中正在运行的方法里面的对象。

全局变量。

Java调用本地方法栈所引用的对象。

 

 

 

Stop-The-World

 

简单理解就是整个jvm被挂起,只能做gc

 gc的对象的分类

gc的对象的分类

 

原因:

 

 gc的对象的分类

类似于上一篇提到的,进行标记的时候,如果一个对象在标记后才new进去的话,这个对象会被马上清除,因为标记的时候这个对象是不存在,也就是说从gc root到这个对象是没有引用链的。

 

Gc root必须保证在一个内存一致性的情况下进行gc,所以会存在全局停顿。

 

危害:

长时间服务停止,没有响应(将用户正常工作的线程全部暂停掉)

遇到HA系统,可能引起主备切换,严重危害生产环境。

  备注:HAHigh Available,高可用性集群。

 gc的对象的分类gc的对象的分类

比如上面的这主机和备机:现在是主机在工作,此时如果主机正在GC造成长时间停顿,那么备机就会监测到主机没有工作,于是备机开始工作了;但是主机不工作只是暂时的,当GC结束之后,主机又开始工作了,那么这样的话,主机和备机就同时工作了。主机和备机同时工作其实是非常危险的,很有可能会导致应用程序不一致、不能提供正常的服务等,进而影响生产环境。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

样例构造:

 gc的对象的分类

printThread线程,每0.1秒打印。

 

 

 gc的对象的分类

MyThread线程,1毫秒占用了0.5m

100毫秒,占用了50m

大概执行10100毫秒后,堆就满了。

 gc的对象的分类

可以看到,3153之后应该马上接着3253,但是并没有,因为3153后对空间满了。Gc暂停了所有程序,这个时候打印线程也被中止了。然后gc进行内存回收,大约用了3504-3153毫秒。

总共经历了2gc