垃圾回收算法

  1. 新生代的回收算法:复制算法。复制算法就是把新生代内存划分为两块内存区域,然后只使用其中的一块内存,待那块内存快满的时候,就把里面的存货对象一次性转移到另外一块内存区域,保证没有内存碎片,接着一次性回收原来那块内存区域的垃圾对象,再次空出一块区域。
  2. 复制算法缺点是如果新生代有1G空间,那么只有512MB的内存是可用的,复制算法的优化是将新生代分为三块,1个Eden区和2个Survivor区,eden区占80%,每块survivor占10%。Eden区满了,触发垃圾回收,将eden区的存活对象一次性转移到空着的survivor区,eden区清空,eden区再次被填满时,就把eden区和上一次使用survivor区的存活对象转移到另一块survivor区域中。
  3. 这样始终保持有一块survivor区域是空着的,最大的好处是保证90%的内存都被使用,只有10%的内存被闲置。

    新生代在什么情况下会进入老年代

  4. 某个对象,躲过 15次垃圾回收之后会被转移进老年代。15次可通过参数”-XX:MaxTrnuringThreshold” 设置,默认15

  5. 动态对象年龄判断。 假如说当前对象的survivor区域里,一批对象的总大小大于这块survivor区域的内存大小的50%那么大于等于这批对象年龄的对象,就可以直接进入老年代了。规则运行逻辑其实是年龄1+年龄2+年龄n的总和超过了survivor的50%,此时会把年龄n以上的对象都放入老年代。
  6. 大对象直接进入老年代。通过参数”-XX:pretenureSizeThreshold”设置,超过这个参数大小的对象会直接进去老年代。
  7. Minor GC后的对象太多无法放入survivor中,会直接进入老年代。
  8. 老年代空间分配担保规则。

首先在执行Minor GC之前,会先检查一下老年代可用内存空间,是否大于新生代所有对象的总大小。
如果老>新放心执行,如果老<新,会看是否设置”-XX:-HandlePromotionFailure”,
如果设置了会判断老年代内存大小,是否大于之前平均每次MinorGC后进入老年代的大小,如果大于,执行MinorGC,正常可以放进survior区域或者放入老年代,异常就是minorGC后大于survivor也大于老年代,此时会发生Handle promotion Failure,触发Full GC,FullGC不仅对老年代回收也会对新生代回收,Full GC后还不够放,就会发生OOM溢出。
如果没有设置-XX:-HandlePromotionFailure或者小于之前平均每次MinorGC后进入老年代的大小,会直接触发Full GC,先对老年代进行垃圾回收后再执行MinorGC

  1. 老年底垃圾回收算法,标记整理算法。首先标记老年代当前存货对象,接着让这些存活对象在内存里移动,把存活对象尽量挪动到一边,一次性把垃圾对象回收掉。

    Stop the world

  2. jvm最大的痛点就是在垃圾回收过程中,jvm在后台会进行stop the world的状态,会停止java系统的所有工作线程