何为GC
GC是garbage collection的缩写,垃圾回收的意思,也可以叫Garbage Collector,也就是垃圾回收器
垃圾回收器的职责
- 分配内存
- 确保任何被引用的对象保留在内存中
- 回收不能通过引用关系找到的对象的内存
GC回收算法
1. 标记回收算法(Mark and Sweep GC)
从"GC Roots"集合开始,将内存整个遍历一次,保留所有可以被GC Roots直接或间接引用到的对象,而剩下的对象都当作垃圾对待并回收,这个算法需要中断进程内其他组件的执行并且可能产生内存碎片
2.复制算法
将现有的内存空间分为两块,每次只使用其中一块,在垃圾回收时将正在使用的内存中的存活对象复制到未被使用的内存块中,之后清除正在使用的内存块中的所有对象,交换两个内存的角色,完成垃圾回收
3.标记压缩算法(Mark-Compact)
先需要从根节点开始对所有可达对象做一次标记,但之后,它并不简单的清理未标记的对象,而是将所有的存活对象压缩到内存的一段,之后清理半截外所有的空间,这种方法既避免了碎片的产生,又不需要两块相同的内存空间,因此其性价比比较高
4.分代
将所有的新建对象都放入年轻代的内存区域,年轻代的特点是对象会很快回收,因此在年轻代就选择效率较高的复制算法,当一个对象经过几次回收后依然存活,对象就会被放入老生代的内存空间,对于新生代适用于复制算法,而对于老生代则采取标记-压缩算法
引用
一个对象,当内存足够的时候,保留在内存中,如果内存紧张则可以抛弃它们,在JDK1.2之后将引用细分为:强引用,软引用,弱引用,虚引用
- 强引用
只要强引用存在,垃圾收集器不会回收掉被引用的对象
- 软引用
用来描述一个对象还有用,但并非必须的对象,在系统将要发生内存溢出异常之前,将会对这些对象进行第二次回收,如果这次回收还没有足够的内存,才会抛出内存溢出异常
- 弱引用
强度比软引用还弱,被弱引用关联的对象只能生存到下一个垃圾收集发生之前,所以内存是否足够都会被回收
- 虚引用
它是最弱的引用,有无这个引用完全不对其生存时间构成影响,也无法通过虚引用来获取一个对象实例,为一个对象设置虚引用关联的唯一目的就是能在这个对象垃圾税收器回收的时候收到一个系统通知
触发GC的条件
- 应用进程空闲的时候,GC会回收空闲进程的内存资源.
- 应用进程繁忙的时候,当需要的内存资源不足的时候,GC会强制执行回收优先级比较低的进程资源,如果还是不足,则再回收两次,还是不足则会报OOM.
减少GC开销的措施
- 尽量少显示的调用System.gc()
- 减少临时对象的引用
- 对象使用完毕之后,设置为null,这样会方便系统查找到空对象,更快回收掉内存
- 能使用基本数据类型的,就尽量不要使用引用类型,基本类型占用的资源比引用类型要小的多
- 尽量少的使用static变量,static变量是全局性,系统在堆中为其分配内存,GC无法回收该内存
- 对于需要使用变成的字符串变量,尽量使用StringBuider/StringBuffer,而不是String,String每赋值一次,就会重新分配一次内存
- 分散创建和删除对象的时间,一次性创建或者删除太多的对象,会导致内存突然变得紧张或者一次性释放太多,不利于内存的合理使用