- 垃圾回收算法种类
- 引用计数算法:如果某一个类被n个变了引用,则标记为n,当n=0的时候可以被清除,jvm不采用这种算法,因为有可能两个对象互相引用。
- 可达性分析算法:会有一个gc-root对象,如果一个对象没有到达这个gc-root的路径,则会被回收,可以作为gc-root的对象有(1)栈中引用对象(2)方法区静态属性引用对象(3)方法区常量引用对象(4)本地方法栈中引用对象
2.对象的引用类型
- 强引用:new
- 软引用:softRerence
- 弱引用:weakRerence
- 虚引用:PhantomReference
3.对象回收流程图
4.方法区回收策略
- 废弃的常量回收与对象回收流程类似
- 废弃的类回收需要满足三个条件(1)类所有的实例都被回收(2)此类的classloader被回收(3)class对象没有被任何地方引用
5.垃圾收集算法
- 标记-清除算法:过程请看上面的流程图,此算法存在两个缺陷(1)效率问题:需要对所有的对象进行判断是否可达(2)空间问题:会产生很多内存碎片空间
- 复制算法:本质上也就是标记-清除算法,区别在于虚拟机会将内存分为两部分,其中一部分内存使用完毕之后,会将这部分的对象复制到另一部分内存中,这样gc只需要清理一部分内存就可以了,但是坏处就是内存使用率太低了,只有一半可以使用,这种算法一般用于新生代内存,因为这部分内存存储的对象生命周期短,可以用一少部分内存(from survivor)存储需要gc的对象,一大部分内存(eden+to survivor)存储不需要gc的对象
- 标记-整理算法:本质上也是标记-清除算法,让所有存活的对象向一端移动,然后清理掉端边界以外的内存。老年代使用。
- 分代收集算法:就是上面介绍的算法中和使用,jvm就是这个做的,首先将堆分为两部分,新生代和老年代,其中新生代(存储生命周期短的对象)使用复制算法,老年代(生命周期长的对象)采用标记-整理算法,如图所示:
6.什么样的对象可以进入老年代呢?
- 大对象,可以由-xx:pretenureSizeThreshold=设置
- 长期存活的对象:放入eden的对象会有一个标示位,age,默认age>=15的时候 就会放入老年代
- 动态年龄判断:以上的流程并不是绝对的,如果相同年龄的对象的总和>=survivor的总和,那么年龄>=这个年龄的对象也会被移动到老年代中。