垃圾回收(GC)

一、什么是GC

Garbage Collection

1、需要GC的内存区域

  • 主要是方法区和堆内存
  • 方法区:存储虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码、运行时常量池;
  • 堆内存:对象实例

2、GC的对象

  • 需要回收的对象就是已经没有存活的对象。
  • 判断对象是否存活的方法:引用计数和可达分析

① 引用计数:每个对象有个引用计数属性,新增一个引用+1,引用释放时计数-1,当计数为0时可回收。此方法无法解决对象循环引用的问题。

② 可达分析:从GCRoots开始向下索引,走过的路劲被称为引用链,当一个对象从GCRoots没有被任何引用链相连接时,则认为对象是不可用的,即不可达对象。

③ GCRoots包括:

  • 虚拟机栈中引用的对象;
  • 本地方法栈中JNI引用的对象;
  • 方法区中常量引用的对象;
  • 方法区中静态属性引用的对象。

3、什么时候触发GC

  • 程序调用System.gc时触发;
  • 系统自身来决定GC触发的时机(根据Eden区和From Space区的内存大小来决定。当内存大小不足时,则会启动GC线程并停止应用线程)
  • GC分为minor GC和 Full GC

① Minor GC触发条件:当Eden区满时,触发Minor GC。

② Full GC触发条件:  

  a.调用System.gc时,系统建议执行Full GC,但是不必然执行

  b.老年代空间不足

  c.方法区空间不足

  d.通过Minor GC后进入老年代的平均大小大于老年代的可用内存

  e.由Eden区、From Space区向To Space区复制时,对象大小大于To Space可用内存,则把该对象转存到老年代,且老年代的可用内存小于该对象大小

4、GC常用的算法

① 标记-清除算法

第一阶段:标记存活或死亡;

第二阶段:清楚死亡对象;

② 标记-压缩算法(标记-整理)

第一阶段:标记存活或死亡;

第二阶段:将存活的对象整理下,放到另外的空间,然后将剩下的对象全部清除

③ 复制算法

将内存平均分成两部分,然后每次只使用其中的一部分,当这部分内存满的时候,将内存中所有存活的对象复制到另一个内存中,然后将之前的内存清空,只使用这部分内存,循环下去

④ 分代收集算法

堆内存分为新生代和老年代;

新生代又被分为Eden、from、to三个区域;

a. 新创建的对象在Eden区,当Eden区满的时候触发一次YoungGC,将Eden区存活的对象放入From区域;

b. 当Eden区再次满的时候,再次触发YoungGC,将Eden区与From区依旧存活的对象复制到To,区域;

c. 当再次YoungGC的时候,将Eden区与To区存活的对象再次复制到From区;

d. 多次YoungGC后,有些对象在From与To区间游荡,触发阈值后,复制到老年代;

e. 当老年代满的时候,触发Full GC。

posted @ 2020-05-17 19:09  啊哈突突突  阅读(147)  评论(0)    收藏  举报