Java的GC回收机制

1 Java有个东西叫垃圾收集器,它让创建的对象不需要像c/cpp那样delete、free掉,你能不能谈谈,GC是在什么时候,对什么东西,做了什么事情?

一,如何gc?
GC是在是一个独立的线程,用来操作堆内存。
Garbage Collection 是根据分代来收集:对年轻代的收集和对老年代的收集;
年轻代又称为eden s0 s1(Survive代) 代,老年代又称为tenured代;年轻代满了的化采用minor gc
他采用的是一种复制算法,就是,预先分配两块相同的空间,只使用其中的一块,当这块空间满的话,会触发morror gc ,通过root节点,先标记所有可达的点,然后再进行copy可达的点,到另一块空间,然后再释放原先的空间的节点。(可以减少内存碎片)
老年代满了则采用full gc,当老年代的对象大于老年代剩余的对象的时候,此时,会触发full gc;
老年代的对象一般都是比较大,直接采用的是标记-删除算法;
当gc超时的时候就会触发OOM;可以设置新生代和老年代的比例来进行对的内存优化;

二,什么时候对象会被GC?
根据跟搜索算法,从roots开始寻找,如果对象不可达,对象会被GC(对象到GC roots没有任何引用链),还有一种算法:引用计数法,他不能很好的解决循环引用问题。(python采用的是这种机制)

   JVM将堆分成了 二个大区  Young 和 Old 如下图:
   
     



   而Young 区又分为 Eden、Servivor1、Servivor2, 两个Survivor 区相对地作为为From 和 To 逻辑区域, 当Servivor1作为 From 时 , Servivor2 就作为 To, 反之亦然

   如下图:

   


   因此当Eden区满的时候 GC执行,这时会将 Eden 区和 From 区中还被引用的对象会被移到 To区 ,个别大对象和部分From对象在To已满的情况下会被放到Old区,如下图:

   



GC操作执行完之后 Eden和 From 区将会为空(无引用对象被回收,有引用对象被移到To和Old区) ,并且From 和 To在逻辑上的 概念调换 , From 概念上变成了To,To变成了From(如果Servior1 原来作为 From 区 ,现在Servior1 现在就作为 To 区),GC执行后结果如下图:

       

HotSpot VM 内存堆的两个Servivor区

。在原始的copying收集算法里,空间被分为两半,叫做semispace。空间分配和回收的过程就是把其中一半用作from来分配空间,当from快满或满足别的一些条件时将可到达的对象复制到to,并将from与to逻辑交换的过程。 
单纯的copying收集不能很好的应对长时间存活的对象,因为那样的对象每次经历收集的时候都还活着,带来拷贝的开销。出于权衡,HotSpot里目前除G1外都采用相似的方式实现分代式GC,并且在young gen都使用copying收集算法。不过它使用的copying算法是原始算法的变种,留一块较大的区域作为eden,在eden与old gen之间设置semispace来作为缓冲,让“中等寿命”的对象尽量在进入old gen之前被收集掉。这就是HotSpot的survivor spaces了。 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值