您的位置:首页 > 编程语言 > Java开发

java垃圾回收策略及对象管理机制

2017-06-07 06:07 281 查看
一、java垃圾收集对象的依据

java垃圾回收主要是针对堆内存对象,堆里有很多对象,在垃圾回收之前,需要判断哪些对象是活的的,哪些对象是死的,然后对死的对象进行回收,java GC不可能把活的对象给回收掉,否则后果不敢设想。GC判断一个对象是否是存活的,主要通过以下几个方法:引用计数器法、可达性分析算法

1、引用计数器法:给对象添加一个引用计数器,当有对象引用时,计数器就加1;当引用失效时,计数器就减1;当计数器为0时,表示没有引用,则说明这个对象是死的,即是无效的对象,这种算法的优点缺点如下:

  优点:效率高,缺点:不能解决对象之间循环引用的问题;

因此目前虚拟机不是使用这种算法来进行垃圾回收的。

2、可达性分析算法:通过GC Roots的对象作为起始点,向下搜索所经过的路径称为引用链,当一个对象到GC roots没有引用链时,就认为这个对象是不可用的;java虚拟机也不是采用这种算法;

java虚拟机的对象被回收之前,都需要经历两次标记法来确定对象到底是生是死,流程图如下:



二、回收垃圾算法

1、标记-清除算法:顾名思义,这种方法经历标记和清除两个阶段,首先标记要清除的对象,其次进行回收,这种算法流程和上述二次标记流程类似;

缺点:1、是效率不高;2、内存碎片多,这种算法会导致内存存在大量的碎片,碎片太多可能会导致程序在分配空间给大对象时,得不到足够的连续内存从而导致再次进行垃圾回收。

2、复制算法:这种算法将内存分为两块,Eden和survivor,统称为新生代,每次只使用一块内存,当这一块内存使用完毕后,就将这一块内存中存活的对象复制到另一块中,然后清空原来第一块内存,每次分配只是移动堆顶的指针,简单、高效。缺点是这种算法的代价是将原来的内存缩小为一半,有点太高了;其实java对象98%都是朝生夕死的,因此按照1:1来分配,而是将年轻代划分为Eden和两块较小的survivor区域,每次只是用Eden和一块survivor区域,回收的时候,将eden和survivor区域中存活的对象复制到另外一块survivor区域。在内存进行分配时,如果新生代(Eden和一块survivor)不够时,将使用另外一块survivor区域,如果这一块survivor区域还不够时,会使用老年代的内存。

缺点:在对象的存活率较高的情况下,效率特别低下;老年代一般使用这种算法,新生代使用此种算法;

3、标记-整理算法:此算法的标记过程和标记-清除算法相同,接下来不是对可回收的对象进行清理,而是让存活的对象向一端移动,清理移动完之后的内存空间(即清理另一端的未使用的内存)

4、分代收集算法:这种算法根据对象的存活周期,将内存分为新生代,老年代,在新生代中,每次垃圾会后都有大量的对象死去,只有少量的对象存活,因此使用复制算法,只需要复制少量的存活对象就可以了,而老年代里的对象存活率较高,都是用标记-整理算法,将存活的对象向一端移动。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息