先从《实战java虚拟机》开始。
垃圾回收算法
主要有引用计数、标记清除、复制、标记压缩、分代算法、分区算法。各类的面试博客或是书籍都已说的很清楚,不再赘述。
主要说下分代算法中的叫做卡表(Card Table)的数据结构,为一个比特位集合,每个比特位对应老年代的一块地址,比特位为1表示这片老年代中的对象持有新生代对象的引用,在这种情况下新生代GC时只需要遍历这一块老年代。
引用
分为强引用、软引用、弱引用、虚引用。后三个引用均在java.lang.ref
包。
- 软引用:SoftReference。GC时未必会回收,内存资源不足时,会回收,不会造成内存泄漏。会附带一个引用队列,可达性改变时,对象入队列,可以根据队列跟踪对象的回收情况。
- 弱引用:WeakReference。GC时必然回收,但垃圾回收器线程的优先级低,因此会有一段存活时间。也有一个引用队列,当对象被回收时加入队列。
- 虚引用:PhantomReference。随时被回收,get方法获取时总是失败。必须和引用队列一起使用,用于跟踪垃圾回收过程。
用处:软引用、弱引用适合保存可有可无的缓存数据。虚引用可以用来跟踪对象的回收时间。
垃圾回收器
串行回收器
单线程进行回收,会有很好的性能表现,但是停顿时间太长。
新生代
新生代使用复制算法。实现简单、逻辑处理高效、无线程切换的消耗。
-XX:+UseSerialGC:串行垃圾回收器。client模式下的默认回收器。
-XX:+PrintGCDetails:输出工作日志
老年代
老年代使用标记压缩算法,可以和多种新生代回收器配合使用,是CMS的备用回收器。
-XX:+UseSerialGC:新生、老年均是串行。
-XX:+UseParNewGC:新生代是ParNew回收器,老年代是串行。
-XX:+UseParallelGC:新生代是Parallel回收器,老年代是串行。
并行回收器
新生代
ParNew回收器简单的将串行回收器多线程化。
-XX:+UseParNewGC:新生代是ParNew回收器,老年代是串行。
-XX:+UseConcMarkSweepGC:新生代是ParNew回收器,老年代是CMS。
-XX:ParallelGCThreads:指定ParNew的线程数。
ParallelGC回收器使用复制算法,与ParNew相像,不同点在于更注重吞吐量。
-XX:+UseParallelGC:新生代是ParallelGC回收器,老年代是串行。
-XX:+UseParallelOldGC:新生代是ParallelGC回收器,老年代是ParallelOldGC。
-XX:MaxGCPauseMillis:设置最大垃圾收集停顿时间。会通过调整java堆的大小和其他参数来尽可能控制STW。
-XX:GCTimeRatio:设置吞吐量大小。假设值设为n,则系统花费不超过1/(n+1)的时间用于垃圾处理。
ParallelGC还具有自适应的GC调节策略。
-XX:+UseAdaptiveSizePolicy:打开自适应GC策略。新生代的大小、eden和survivior的比例、晋升老年代的年龄等参数会自动调整。
老年代
ParallelOldGC使用标记压缩算法。
-XX:+UseParallelOldGC:新生代是ParallelGC回收器,老年代是ParallelOldGC。
-XX:ParallelGCThreads:设置线程数量。