java basic-GC

一  JVM把堆分为很多区,如下图

新生代:新创建的对象都是用新生代分配内存,Eden空间不足时,触发Minor GC,此时会把存活的对象转义金Survivor区。

老年代:用于存放经过多次Minor GC之后依然存活的对象

新生代的GC(Minor GC): 新生代通常存活时间短,使用copying算法回收,将Eden和Survivor1(FromSpace)存活的对象复制到Survivor2(ToSpace),然后直接清理掉Eden和Survivor1的空间。

使用空闲指针方式来控制GC,指针保持最后一个分配的对象在新生代区间的位置,当新对象要分配内存时,用于检查空间是否足够。连续分配对象时,对象逐渐从Eden到Survivor再到老年代。

老年代的GC(Major GC/Full GC):老年代对象存活时间长,比较稳定,因此采用标记(Mark)算法进行回收,所谓标记算法就是扫描出存活的对象,再回收未被标记的对象。

回收后空间要吗合并,要吗标记出来下次分配,减少内存碎片带来的效率损耗。

二  GC的触发时间

1 程序空闲的时候

2 手动 system.gc()

3 java堆内存不够用的时候,会触发,第一次触发GC后内存依然不够用,会第二次触发,如果还不够用,就out of memory

三 GC回收什么东西

1  引用计数为空的对象

2 从GC Root开始搜索,且搜索不到的对象

  跟搜索算法:以一系列名为 GC Root的对象作为起点,从这些节点开始往下搜索,搜索走过的路径称为引用链,当一个对象到GC Roots没有任何引用链的时候,则就证明此对象是不可用的。

3 从root搜索不到,而且经过第一次标记、清理后,仍然没有复活的对象

四  GC做什么

总的来说是删除不使用的对象,腾出内存空间。

五 容易发生内存泄漏的情况

1 静态集合类像HashMap、Vector等,特别是如果集合里存了集合或者存了对象而且该对象内有集合。

2 各种连接,数据库连接,网络连接,IO连接等没有显示调用close关闭,不被GC回收导致内存泄露。

3 监听器的使用,在释放对象的同时没有相应删除监听器的时候也可能导致内存泄露。

猜你喜欢

转载自www.cnblogs.com/hup666/p/10679351.html