gc的对象的分类

Gc对象的性质

 

可触及

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

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

 

 

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

可复活

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

 

 

 

不可触及

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

 

 

 

 

 

使用finalize方法来复活对象

 

 

 

 

使用finalize的问题:

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

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

 

根的引用链。

 

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

全局变量。

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

 

 

 

Stop-The-World

 

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

 


 

原因:

 

 

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

 

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

 

危害:

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

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

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

 

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

 

 

 

 

 

 

 

 

 

 

 

 

 

 

样例构造:

 

printThread线程,每0.1秒打印。

 

 

 

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

100毫秒,占用了50m

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

 

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

总共经历了2gc

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值