JAVA的垃圾收集过程(3)

     大家好,上一篇我们讲到了java如何对垃圾进行收集,提到了三种垃圾收集算法,以及将各种收集算法进行组合优化的分代收集,今天的标题虽然是JAVA的垃圾收集过程,但是我们会主要讲解一些关于JAVA内存分配的知识。

    其实,在JAVA所提倡的自动内存管理中,我们最终可以归结为自动化的解决了两个问题,一个问题是对象内存分配,一个问题是如何回收分配给对象的内存,关于回收内存,我们之前已经进行了详细的解释,下面我们来讲解一些关于对象内存分配的知识。

    1.对象优先分配在Eden

    大多数情况下,对象的内存分配会发生在Eden区中,当Eden区没有足够的内存时,将会触发一次Minor GC。

    JAVA中的垃圾回收分为Minor GC以及Full GC,Minor GC意为年轻代GC,由于年轻代对象大都为朝生夕死的对象,所以Minor GC发生频率比较频繁,速度也比较快。

    我们所说的Full GC为老年代GC,但是当出现Full GC时,一般都会伴随着至少一次的Minor GC,不过这种情况并非绝对,主要还是和垃圾收集器的收集策略有关。

    2.大对象直接进入老年代:

    这里所说的大对象是指需要消耗大量连续的内存空间的JAVA对象,例如长度较大的字符串或者数组,大对象的出现对于虚拟机来说是不利的,但是如果我们的大对象是朝生夕死的,那么将是更为不利的情况,因为大对象的出现经常会导致内存还有大量的空间就提前触发垃圾回收动作。

    3.长期存活的对象进入老年代:

    由于虚拟机会采用分代回收机制,所以就有必要识别哪些对象需要放在年轻代,哪些对象需要放在老年代中,在虚拟机中会为对象定义一个年龄计数器,如果对象在Eden经历过一次垃圾回收后还存活,移动至Survivor中,则对象年年龄加1,之后每经历一次垃圾回收,如果对象还存活,则将对象年龄加1,当对象年龄达到设置阈值时,将被移动到老年代,默认阈值为15,可以通过-XX:MaxTenuringThreshold来进行设置。

    4.空间分配担保:

    在发生Minor GC之前,虚拟机会检查老年代中的最大的可用连续内存空间是否大于年轻代中所有存活对象的总空间,如果这个条件成立,则Minor GC是安全的,因为老年代可以满足所有年轻代存活对象进入老年代的极端情况。

    如果不满足,虚拟机则会查看HandlePromotionFailure设置是否允许担保,如果允许,则检查老年代中的最大的可用连续内存空间是否大于之前每次晋升老年代对象的平均大小,如果满足就会触发一次Minor GC,如果不满足则会触发一次Full GC。    

    但是这种策略在JDK6之后有了改变:老年代中的最大的可用连续内存空间如果大于之前每次晋升老年代对象的平均大小或者新生代中存活对象的总大小,则触发一次Minor GC,否则进行Full GC。

    其实归根结底,JAVA中的内存分配和垃圾回收策略都是为了使内存得到更高效的利用,并且希望将更多的内存管理交由机器来处理从而解放程序员劳动力,使程序员可以从复杂的内存管理中抽身并减少人为管理内存中出现的错误。

    好了,今天就和大家分享这些知识,感谢大家的支持,如果大家觉得我们的文章对您有用,请记得关注我们,每天一篇干货文章和实用面试题哦。

JAVA的垃圾收集过程(3)_第1张图片


你可能感兴趣的:(java)