Java虚拟机学习-(3)垃圾回收

垃圾收集(GC)需要两件事:
    如何找出需要回收的内存?
    如何回收这些内存?
 
 

找出需要回收的内存

    引用计数法(仅供学习)、可达性分析法、方法区回收条件
 

引用计数法

    给对象头添加一个引用计数器,被引用计数器就加1,引用失效减1,计数器为0,对象不再被引用,可被回收。
    该算法存在孤岛问题,如下图,也就是A对象引用了B,B引用了A,A、B的引用计数器均为1,但A、B已不再被其他地方引用,也无法被回收。
 
 

可达性分析法

通过GC Roots对象向下查找,走过的路径形成引用连,引用连到达不了的对象判定可回收。如下图的Obj5、Obj6、Obj7。

 

GC Roots对象包括:
  • 虚拟机栈(栈帧中的本地变量表)引用的对象。
  • 方法区中静态类属性引用对象。
  • 方法区中常量引用的对象。
  • 本地方法栈中JNI(Native方法)引用的对象。
 
引用:
  • 强引用 Strong Reference:垃圾收集器永远不会回收被引用的对象。Object obj = new Object()。
  • 软引用 Soft Reference:GC后内存不足,会将软引用的对象放入回收队列进行回收,还不足就内存溢出,一般用在缓存上。
  • 弱引用 Weak Reference:GC直接回收。
  • 虚引用 Phantom Reference:无法通过引用获取对象,对象回收时收到一个系统通知。
 
方法区回收
  • Java堆中不存在该类的实例
  • 加载该类的ClassLoader被回收
  • 该类的java.lang.Class没被引用,无法反射访问该类方法。
    

回收这些内存

 

标记-清除算法(Mark-Sweep)

    标记出需要回收的对象,也就是上文提到的方法,然后统一回收标记的对象。
    缺点:标记、清除效率都不高,且存在内存碎片化问题
    
由上图可见,回收后实际空闲的空间为5,但是如果申请4个内存,还是不足,因为这5个内存是碎片化内存,不连续。
 

复制算法(Copying)

将内存分为相同两块,当一块用完后,就将存活对象复制到另外一块,然后将原本那块内存回收。
缺点:空间成功太高,得留出来一半空间做保留区域。
    

标记-整理算法(Mark-Compact)

将存活对象向一端移动,然后清理掉边界以外的内存。

分代收集算法(Generational Collection)

根据对象存活周期,将内存划分为几块:新生代、老年代。然后根据每个年代特点,选用适合的收集算法。
新生代存活对象较少,一般选用复制算法,老年代对象存活率高,使用标记清理或者标记整理算法。
 
其中新生代还有个区域,TLAB(Thread Local Allocation Buffer),JVM默认给每个线程开辟了一个buffer区域,用来加速对象分配,线程私有。对象优先在TLAB上分配,对象过大会在Eden共享区分配。
 
新生代(又称年轻代)
 
新生代又分为Eden与2个Survivor,默认比例8:1:1,可通过参数-XX:SurvivorRatio设置,默认8.
每次只会使用一个Survivor。当Minor GC时,会将Eden与Survivor的存活对象复制到另外一个未使用的Survivor,然后清理Eden与Survivor。
 
老年代
 
进入老年代的条件:
  • 大对象直接在老年代分配,-XX:PretenureSizeThreshold可设置,单位B。
  • 长期存活的对象进入老年代,没进行一次Minor GC,年龄加1,默认15晋升老年代,-XX:MaxTenuringThreshold设置。
  • 动态对象年龄判断:Survivor中相同年龄所有对象大小综合大于Survivor空间的一半,年龄大于该年龄的对象直接进入老年代。
  • 在Minor GC时,Survivor空间不够用,多出来的对象就会进入老年代。
 

垃圾收集器

 

年轻代

  • Serial:GC时单线程,回收过程暂停一切用户线程,使用复制算法。
  • ParNew:GC时多线程,回收过程暂停一切用户线程,多CPU会降低STW时间。
  • Parallel Scavenge:GC时多线程,最求CPU吞吐量。
 

老年代

  • Serial Old:与Serial对应,单线程,使用标记-整理算法。
  • Parallel Old:与Parallel Scavenge对应,最求CPU吞吐量。
  • CMS:追求最短GC停顿时间。缺点较明显,CPU敏感,无法处理浮动垃圾,因为使用标记-清除算法,会有内存碎片,需要依赖Full GC进行整理。
 
G1:并行与并发、分代收集、空间整合、可预测停顿。建立多个大小相等的Region区域,然后判断回收价值,设定回收优先级。
每个Region不是独立的,因为存在对象引用。为避免GC时对所有Region扫描,使用了Remembered Set记录。
如下图,Region1中A对象引用Region2中的B对象,则Region2会在B建立引用时,在自己的Remembered Set中记录下Region1,然后Region2在GC时,就会带上Region1一起扫描。
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值