java 垃圾回收机制

JVM的内存结构包括五大区域:程序计数器、虚拟机栈、本地方法栈、堆区、方法区。其中程序计数器、虚拟机栈、本地方法栈3个区域随线程而生、随线程而灭,因此这几个区域的内存分配和回收都具备确定性,就不需要过多考虑回收的问题,因为方法结束或者线程结束时,内存自然就跟随着回收了。而Java堆区和方法区则不一样、不一样!(怎么不一样说的朗朗上口),这部分内存的分配和回收是动态的,正是垃圾收集器所需关注的部分。

垃圾收集器在对堆区和方法区进行回收前,首先要确定这些区域的对象哪些可以被回收,哪些暂时还不能回收,这就要用到判断对象是否存活的算法!

怎样判断是对象否为垃圾?

引用计数法

引用计数法是为对象添加一个引用计数器,然后用一块额外的内存区域来存储每个对象被引用的次数。 当对象每有一个地方引用它时,那我们对该对象的引用计数就会加1,反之每有一个引用失效时,我们对该对象的引用计数就会减1。 当对象的被引用次数为0时,那么我们可以认为这个对象是不会被再次使用了,通过这种方式我们能快速直观的定位到这些已死的对象,从而进行清理。

引用计数法的缺陷

需要额外的空间记录对象的引用次数,并且需要动态的维护这个统计数。

无法解决循环引用的问题,当两个对象A和B互相引用的时候,这种情况引用计数法是无法检测到的

 

可达性分析法

可达性分析法是通过以所有的“GC Roots”对象为出发点,如果无法通过GC Roots的引用追踪到的对象,那我们认为这些对象就不会再次被使用了

哪些对象可以作为GC Roots

1、虚拟机栈中的本地变量所引用的对象。

2、方法区中静态属性引用的对象。

3、方法区中常量引用的对象。

4、本地方法中(Native方法)引用的对象。

5、虚拟机内部的引用对象(类记载器、基本数据对应的Class对象,异常对象)。

6、所有被同步锁(Synchronnized)持有的对象。

7、描述虚拟机内部情况的对象(如 JMXBean、JVMTI中注册的回调、本地缓存代码)。

8、垃圾搜集器所引用的对象。
垃圾回收算法

 标记清除

标记清除法是先标记对象是否存活,然后把已死的对象统一进行清除

不连续空间 清除后会造成内存造成了很多不连续的空间,这也就是我们常说的空间碎片,这样的空间碎片太多让我们申请对象时申请空间变得麻烦,而且当有大对象创建的时候,我们明明有可以容纳的总空间,但是空间都不是连续的造成对象无法分配。 不稳定 当内存中大量对象都是需要回收的时候,标记和清除比较耗时,性能不稳定。

标记复制

标记复制法会把内存划分出三块区域,一块主区用来创建新的对象,两块复制区用来存放存活的对象,这两块区域同时只会有一块使用,每次GC都会把存活的对象复制到另外一块复制区,这样始终保证有一块空白连续的内存空闲出来用于下次GC时存放存活的对象; 因为存活的对象都被复制到了新的一块空白的内存区,所以对象存储都是连续性的,而且原来的区域不需要考虑保留存活的对象,所以可以直接一次性清除所有对象

标记复制法的问题

会浪费一部分内存

通过上面的图我们也不难发现,总是会有一块空闲的内存区域是利用不到的,这也造成了资源的浪费。

存活对象多会非常耗时

既然是在大多数对象都是已死对象适用,那么也说明了如果大多数对象都是在存活的情况下,那么标记复制法就显得没有那么好了,因为需要把大多数对象复制到另外一个区域是非常耗时的。

需要担保机制

因为复制区有一块空间的浪费,为了减少浪费所以我们会把复制区分配控制在很小的区间,如果存活的对象比较多,那么这时复制区的空间可能不够容纳这些对象,这时就需要担保机制(从别的内存拿,释放了 

标记整理

标记整理法是使用另外一种方式解决空间碎片的问题,此方式会在对象标记过后,把存活的对象向内存的另外一端移动,最后再把整理边界之外的区域统一进行清除,以这样的方式也避免了空间碎片的产生

 标记整理法的不足

整理过程时间比耗时

因为移动对象需要对其引用的地址进行变更,所以这个过程需要停止所有“用户线程”(也就是 stop the word ),从而造成应用程序的停顿,如果存活的对象越多那么迁移对象的过程时间就可能越长

各种垃圾回收算法适用场景

 

1.  标记清除法

特点:        简单、速度快,但会有空间碎片,空间碎片会导致后面的GC频率增加。

适合场景:    只有小部分对象需要进行回收的,因为回收对象太多,其清除的时间就会越长。         关注引用停顿时间,因为收集速度快,用户线程停顿的时间较短。

2.   标记复制法

特点:        收集速度快,可以避免空间碎片,但是有空间浪费,存活对象较多的情况下会        非常耗时,而且需要担保机制。 适合场景:    只有少量对象存活的,因为需要把存活对象复制到新的内存区域,所需要复制        的对象越多那么其复制的时间就会越长,比较适合新生代的垃圾回收。

3.  标记整理法

特点:        相对于标记复制法不会浪费内存空间,相对标记清除法则可以避免空间碎片,        但是速度比其他两个算法慢。

适合场景:    内存吃紧,又要避免空间碎片的场景。

总结:

最后我们根据各种算法的特性,标记清除法、标记整理法比较适用于老年代的垃圾回收,因为老年代的对象一般都是存活的比较多,而内存也比较吃紧。 而标记复制法则适用于我们的新生代的垃圾回收,因为新生代大多数的对象都是朝生夕死的,存活下来的对象比较少。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值