垃圾回收算法
JVM的垃圾回收算法并不是引用计数法,而是可达性分析算法
可达性分析算法: 在判断一个对象是否可以被GC的时候,JVM通过深度优先搜索判断当前对象的应用是否可以到达GC ROOT,如果没有,则下一次GC时,这个对象会被回收
-
在Java 中GC ROOT可能的类型包括
- 虚拟机栈的引用
- 方法去中类静态属性的引用
- 方法区中常量的引用
- 本地方法栈中JNI的引用
-
四种引用类型
- 强引用(default):即使OOM也不会被回收
- 软引用: OOM前会被回收
- 弱引用: 在下一次GC时,会被回收
- 虚引用: 为一个对象设置虚幻引用的唯一作用是,这个对象在被回收时,收到一个系统通知
方法区中对象的回收
- 常量池中的对象,例如一个字符串“abc”,如果一个没有String对象引用它,也没有其他地方引用,如果有必要的话,这个字符串会被回收掉
- 对于类的回收,需要满足三个条件
- 该类的所有实例已经被回收
- 加载该类的所有classloader已经被回收
- 该类对应的java.lang.Class对象没有在任何地方被引用,无法在任何地方通过反射访问该类的方法
在大量使用反射,动态代理,CGLIB等ByteCode框架的以及OSGI的,需要在方法区进行垃圾回收
垃圾回收算法
标记-清除
- 效率问题
- 标记清楚以后会产生大量的不连续的内存碎片
复制算法
它将内存空间分为两部分,每次只使用其中的一部分,这部分内存使用完了以后,将还存活的对象复制到另一块内存模块上
- 非常适用于新生代的GC算法
- 具体实现: 一块Eden区,两块survivor区
标记-整理算法
类似标记-清除算法,先是对可回收的对象进行标记,然后这些对象的内存向一边进行移动,然后后整块清除
- 此回收算法适用于老年代
垃圾回收器
- 目前所有的新生代gc都是需要STW的(Stop the world)
- Serial:单线程STW,复制算法
- ParNew:多线程并行STW,复制算法
- Parallel Scavange:多线程并行STW,吞吐量优先,复制算法
- G1:多线程并发,可以精确控制STW时间,整理算法
- 对象优先在Eden区分配存储空间,当Eden区内存不足时,将会发起一场Minor GC
- 大对象直接进入老年代 : 尽量少产生一些短命的大对象
- 长期存活的对象直接进入老年代