内容简介: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的循环引用。
当然,还有更细致的分法:
- 强引用
String a = new String()
就是这样的,强引用存在,GC就不能回收对象 - 软引用
有用单非必须的对象,这些对象在内存快溢出就会被回收,回收内存依旧不够才会抛出异常 - 弱引用
比软引用还非必要,每次GC来的时候都会被回收 - 虚引用
最弱的引用,无法通过这个引用来获取对象,唯一的作用是在被回收事给系统一个通知
1x02可达性算法
这个比上面高大上一点,Java通过可达性分析来判定对象是否还被引用。什么的可达性分析呢:
Java会从一些叫做GCRoot的对象开始向下遍历,可以遍历到的对象,就是被引用的对象,不可以遍历到的对象就是不可达对象,就是死掉的对象了:
蓝色表示可达对象灰色表示不可达对象
在图上可以看到,从GCRoot开始,蓝色部分的对象都可以被遍历到,儿灰色部分,即使 Object A 可以遍历到 Object B 和Object C,但是却没有了GCRoot 引用,所以就属于不可达的死亡对象了
(是不是找不到对象就可以死了 T^T
)。
GCRoot 包括:栈中引用对象,方法区静态引用对象,方法区常量引用对象,本地方法引用对象(Native层的)
II GC回收垃圾的算法
既然已经能判断了垃圾有哪些,接下来就简单讲讲对垃圾对象如何清理
2x01 标记-清除算法
跟名字一样,先把死掉的对象标记出来,然后清除,大部分算法是基于这个思想,不足之处也很明显,1是效率问题,标记和清除的过程都慢,2是空间问题,清除之后会带啦大量的不连续碎片空间。小的碎片会放不下大对象,导致大对象创建时又会触发一次回收
回收前
回收后
2x02 复制算法
为了解决效率问题,有了复制算法,这种算法将内存分成相同大小的两块
回收前
回收后
其实并不是非要等比划分内存的,大部分对象死的很早Hotspot是划分了三块区域,一块大的两块小的,大的叫Eden,小的叫survivor,大小比例为8:1。清理时将Eden和survivor中存活的对象复制到另一块survivor内存上,然后,清理掉用过的两块内存,下次再用。当survivor不够大的时候,需要依靠新的分配担保去拓展空间。
2x03 标记-整理算法
综合复制和标记算法,整理算法会把有用的存活对象向y,一端移动,这样避免了复制算法浪费那么多内存,也不会像普通标记回收算法一样导致内存碎片过于严重。
回收前
回收后
2x04 分代收集算法
将java堆内存分成老年代,新生代。根据经验,新生代死亡比较快,老年代比较持久。所以一般新生代区域使用复制方法,只需要复制几个就可以了,老年代比较持久,所以一般用标记清除,或标记整理来回收。
以上所述就是小编给大家介绍的《Java的GC如何玩弄对象》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- OC对象的本质 实例对象,类对象,元类对象
- 可迭代对象,迭代器(对象),生成器(对象)
- 重学前端学习笔记(七)--JavaScript对象:面向对象还是基于对象?
- Webform 内置对象 Session对象、Application全局对象,ViewState详细介绍
- 对象.原型链,函数.原型对象
- Java 对象组成,对象头分析
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
The Pragmatic Programmer
Andrew Hunt、David Thomas / Addison-Wesley Professional / 1999-10-30 / USD 49.99
本书直击编程陈地,穿过了软件开发中日益增长的规范和技术藩篱,对核心过程进行了审视――即根据需求,创建用户乐于接受的、可工作和易维护的代码。本书包含的内容从个人责任到职业发展,直至保持代码灵活和易于改编重用的架构技术。从本书中将学到防止软件变质、消除复制知识的陷阱、编写灵活、动态和易适应的代码、避免出现相同的设计、用契约、断言和异常对代码进行防护等内容。一起来看看 《The Pragmatic Programmer》 这本书的介绍吧!