简述JAVA内存分配与垃圾回收

简述JAVA内存分配与垃圾回收_第1张图片

简单来说:堆 = 新生代 + 老年代 (Permanent忽略)

新生代:通常用来保存新生的对象。

老年代:1:保存年龄超过默认值的对象(默认15,可设置)、

             2:触发分配担保机制而提前存入的对象

             3:大对象(可设定,应避免使用大对象)

             4:忘了。。。以后补上

新生代与老生代的大小比例通常为1:2

新生代中划分为Eden和两个Survivor比例为8:1:1Eden区是连续的内存空间,因此在其上分配内存极快

    新生代中内存分配采取停止-复制算法,将新生代分为Eden和两个Survivor。新生对象保存在Eden中(大对象除外),当Eden空间被占满时,触发一次Minor GC,清除消亡的对象,之后Eden中还存活的对象年龄+1,并将其移动到其中一个Survivor中(此时,Survivor1是空白的,两个Survivor总有一个是空白的)(循环...),

    当Survivor0也满的时候,将其中仍然活着的对象直接复制到Survivor1,以后Eden区执行Minor GC后,就将剩余的对象添加Survivor1(此时,Survivor0是空白的)。

    若Survivor没有足够的空间放置对象,则触发分配担保机制将对象提前放入老年代中。(默认年龄超过15的对象则直接晋升老年代,为Survivor 腾出空间)

    老年代采用标记-整理算法标记出仍然存活的对象(存在引用的),将所有存活的对象向一端移动,以保证内存的连续。

     在发生Minor GC时,虚拟机会检查每次晋升进入老年代的大小是否大于老年代的剩余空间大小,如果大于,则直接触发一次Full GC,否则,就查看是否设 置了-XX:+HandlePromotionFailure(允许担保失败),如果允许,则只会进行MinorGC,此时可以容忍内存分配失败;如果不 允许,则仍然进行Full GC(这代表着如果设置-XX:+Handle PromotionFailure,则触发MinorGC就会同时触发Full GC,哪怕老年代还有很多内存,所以,最好不要这样做)。


分配担保机制触发过程:1:Minor GC----Survivor空间不足无法存放-----检查老年代空间----如果老年代空间不足则触发Full GC,如果足够则将Eden中年龄不足的对象转移到老年代。

------------------------------------

垃圾回收

1:可达性分析  : 通过引用链从顶向下搜索对象,若对象可达则忽略,若对象不可达则给予标记。

2:保存到“抢救队列”再下次GC时,被标记为不可达的对象将被先存放在一个Queue中。

3:检查且执行finalize:虚拟机用一个线程逐个检查该队列中对象的finalize方法,若finalize存在,且没有被运行过(该方法仅运行一次),则执行对象的finalize,如果在方法中对象重新获得了引用,则取消不可达标记,对象重新活跃。

4:生存or灭亡 :  若finalize方法执行后仍然处于不可达状态则对象被回收。

PS:java虚拟机不保证finalize的执行(完全不靠谱),所以最好不要使用该方法做想要的功能,编程时尽量忽略该方法。





你可能感兴趣的:(java,GC,垃圾回收,内存分配)