面试问题GC回收机制

内存回收机制:

内存回收就是释放掉在内存中已经没有直接或者间接引用的对象所占的空间。

首先,要判断怎样的对象是没用的对象。这里有2种方法:

1.采用标记计数的方法:

给内存中的对象给打上标记,对象被引用一次,计数就加1,引用被释放了,计数就减一,当这个计数为0的时候,这个对象就可以被回收了。当然,这也就引发了一个问题:循环引用的对象是无法被识别出来并且被回收的。所以就有了第二种方法:

2.采用根搜索算法:

从一个根出发,搜索所有的可达对象,这样剩下的那些对象就是需要被回收的

判断完了哪些对象是没用的,这样就可以进行回收了

最简单的,就是直接清空那个需要被回收的对象。但是这又出现了一个问题,就是内存会被分为一块一块的小碎片。

为了解决这个问题,可以采用第二种方法,就是在之前的基础上将存活的对象给整理一下,使他们变成一个连续的内存,从而释放出连续的较大的内存空间。

还有一中回收方法就是采用复制的办法:将内存分为2块,一块用来存放对象,另一块用来放着,当存放对象的那块满了以后就将上面存活的对象给复制过来,然后在这块内存上工作,并且将之前的内存清空,当自己这块满了以后再复制回去,如此反复。


比较效率的一中做法是将以上的几种方法给结合起来。

首先将内存分块,分为新生代,老年代和永久代。

永久代用来存放代码,等一些基本不改变的数据,

新生代用来存放刚产生的一些对象,新生代又可分为3块。分别为Edon区,Survivor0,survivor1,刚产生的对象是放在Edon区中,当这个区块放满了以后就将其存活的部分复制到survivor0块中,并且将Edon区中的数据清空,等到survivor0满了就将其中的存活的数据放到survivor1中,清空survivor0,垃圾回收到了一定次数还未被回收的对象,就可以放到老年区。一般来说,刚才产生的对象大多是要在下一次垃圾回收的时候就要被回收掉的,只有一小部分对象会被保留下来,这些被保留下来的对象都是比较稳定的,所以在老年区中的对象回收方法可以采用整理的方法,而在Edon区等新生代中采用复制的方法比较好。

 

垃圾回收他是在虚拟机空闲的时候或者内存紧张的时候执行的,什么时候回收不是由程序员来控制的,这也就是java比较耗内存的原因之一。

还有在垃圾回收的时候当检测到对象没有用了,需要被回收的时候并不会马上被回收,而是将其放入到一个准备回收的队列,去执行finalize方法。。然等到下次内存回收的时候要是他还是没有被任何人引用的话,就将其给回收了。(如果在finalize方法中重新给对象加个引用,这样对象是有可能不会被回收的)不过finalize方法不推荐使用,他跟C++中的析构函数不同,我们既不能确定什么时候他回被回收,也不能保证这个方法一定会被执行。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值