Java的GC如何玩弄对象

栏目: Java · 发布时间: 7年前

内容简介:Java的GC如何玩弄对象

Java的GC是什么,应该做 Java 的人都知道。但是其实GC的历史要比Java早,Java出现之前,人们就开始研究:

  • 哪些内存需要回收
  • 哪些内存什么时候回收
  • 怎样回收

然后就有了GC,而Java解决的这3件事情,就目前看来,效果还可以。解决了很多的内存问题。但是,GC并不能解决所有内存动态分配的问题,尤其是高并发的软件中,了解GC,方便解决内存溢出问题,更好的控制和调节程序的回收和分配内存。

I 对象生死判定算法

感叹一下乔布斯当年看中的两项技术Internet 和OOP Language,现在都如日中天,不愧是乔帮主。

Java是OOP的经典语言之一,OOP语言号称万物皆对象,对象用不到了,那就应该离开内存了,这就是对象的死亡。是不是死掉的呢

死掉的对象,自然需要GC来处理,但是GC怎么知道对象已经死掉了呢?

1x01引用计数算法

就是给每个对象添加一个引用计数器,当对象被引用一次,计数器就+1;引用失效时,计数器就-1。当计数器为0,就说明对象死了。这个方法实现简单,效率也可观。但是,主流的JVM没用这个算法,因为这个算法很难解决循环引用的问题。

什么是循环引用?

就是多个对象,互相引用对方作为属性,下面就是A依赖B,B依赖C,C依赖A的循环引用。

Java的GC如何玩弄对象

当然,还有更细致的分法:

  • 强引用
    String a = new String() 就是这样的,强引用存在,GC就不能回收对象
  • 软引用
    有用单非必须的对象,这些对象在内存快溢出就会被回收,回收内存依旧不够才会抛出异常
  • 弱引用
    比软引用还非必要,每次GC来的时候都会被回收
  • 虚引用
    最弱的引用,无法通过这个引用来获取对象,唯一的作用是在被回收事给系统一个通知

1x02可达性算法

这个比上面高大上一点,Java通过可达性分析来判定对象是否还被引用。什么的可达性分析呢:

Java会从一些叫做GCRoot的对象开始向下遍历,可以遍历到的对象,就是被引用的对象,不可以遍历到的对象就是不可达对象,就是死掉的对象了:

Java的GC如何玩弄对象 蓝色表示可达对象灰色表示不可达对象

在图上可以看到,从GCRoot开始,蓝色部分的对象都可以被遍历到,儿灰色部分,即使 Object A 可以遍历到 Object B 和Object C,但是却没有了GCRoot 引用,所以就属于不可达的死亡对象了

(是不是找不到对象就可以死了 T^T )。

GCRoot 包括:栈中引用对象,方法区静态引用对象,方法区常量引用对象,本地方法引用对象(Native层的)

II GC回收垃圾的算法

既然已经能判断了垃圾有哪些,接下来就简单讲讲对垃圾对象如何清理

2x01 标记-清除算法

跟名字一样,先把死掉的对象标记出来,然后清除,大部分算法是基于这个思想,不足之处也很明显,1是效率问题,标记和清除的过程都慢,2是空间问题,清除之后会带啦大量的不连续碎片空间。小的碎片会放不下大对象,导致大对象创建时又会触发一次回收

Java的GC如何玩弄对象 回收前

Java的GC如何玩弄对象 回收后

Java的GC如何玩弄对象

2x02 复制算法

为了解决效率问题,有了复制算法,这种算法将内存分成相同大小的两块

Java的GC如何玩弄对象 回收前

Java的GC如何玩弄对象 回收后

Java的GC如何玩弄对象

其实并不是非要等比划分内存的,大部分对象死的很早Hotspot是划分了三块区域,一块大的两块小的,大的叫Eden,小的叫survivor,大小比例为8:1。清理时将Eden和survivor中存活的对象复制到另一块survivor内存上,然后,清理掉用过的两块内存,下次再用。当survivor不够大的时候,需要依靠新的分配担保去拓展空间。

2x03 标记-整理算法

综合复制和标记算法,整理算法会把有用的存活对象向y,一端移动,这样避免了复制算法浪费那么多内存,也不会像普通标记回收算法一样导致内存碎片过于严重。

Java的GC如何玩弄对象 回收前

Java的GC如何玩弄对象 回收后

2x04 分代收集算法

将java堆内存分成老年代,新生代。根据经验,新生代死亡比较快,老年代比较持久。所以一般新生代区域使用复制方法,只需要复制几个就可以了,老年代比较持久,所以一般用标记清除,或标记整理来回收。


以上所述就是小编给大家介绍的《Java的GC如何玩弄对象》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

The Pragmatic Programmer

The Pragmatic Programmer

Andrew Hunt、David Thomas / Addison-Wesley Professional / 1999-10-30 / USD 49.99

本书直击编程陈地,穿过了软件开发中日益增长的规范和技术藩篱,对核心过程进行了审视――即根据需求,创建用户乐于接受的、可工作和易维护的代码。本书包含的内容从个人责任到职业发展,直至保持代码灵活和易于改编重用的架构技术。从本书中将学到防止软件变质、消除复制知识的陷阱、编写灵活、动态和易适应的代码、避免出现相同的设计、用契约、断言和异常对代码进行防护等内容。一起来看看 《The Pragmatic Programmer》 这本书的介绍吧!

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

SHA 加密
SHA 加密

SHA 加密工具

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具