Java必知必会:JVM是啥( 三 )


Java必知必会:JVM是啥

文章插图
 
  1. 分代收集算法(Generational Collection)
分代收集算法是目前大部分JVM的垃圾收集器采用的算法 。它的核心思想是根据对象存活的生命周期将内存划分为若干个不同的区域 。一般情况下将堆区划分为老年代(Tenured Generation)和新生代(Young Generation),在堆区之外还有一个代就是永久代(Permanet Generation) 。老年代的特点是每次垃圾收集时只有少量对象需要被回收,而新生代的特点是每次垃圾回收时都有大量的对象需要被回收,那么就可以根据不同代的特点采取最适合的收集算法 。
Java必知必会:JVM是啥

文章插图
 
新生代(Young Generation)的回收算法(以复制算法为主)
  • 所有新生成的对象首先都是放在年轻代的 。年轻代的目标就是尽可能快速的收集掉那些生命周期短的对象 。
  • 新生代内存按照8:1:1的比例分为一个eden区和两个survivor(survivor0,survivor1)区 。一个Eden区,两个 Survivor区(一般而言) 。大部分对象在Eden区中生成 。回收时先将eden区存活对象复制到一个survivor0区,然后清空eden区,当这个survivor0区也存放满了时,则将eden区和survivor0区存活对象复制到另一个survivor1区,然后清空eden和这个survivor0区,此时survivor0区是空的,然后将survivor0区和survivor1区交换,即保持survivor1区为空,如此往复 。
  • 当survivor1区不足以存放 eden和survivor0的存活对象时,就将存活对象直接存放到老年代 。若是老年代也满了就会触发一次Full GC(Major GC),也就是新生代、老年代都进行回收 。
  • 新生代发生的GC也叫做Minor GC,MinorGC发生频率比较高(不一定等Eden区满了才触发) 。
老年代(Tenured Generation)的回收算法(以标记-清除、标记-整理为主)
  • 在年轻代中经历了N次垃圾回收后仍然存活的对象,就会被放到老年代中 。因此,可以认为老年代中存放的都是一些生命周期较长的对象 。
  • 内存比新生代也大很多(大概比例是1:2),当老年代内存满时触发Major GC即Full GC,Full GC发生频率比较低,老年代对象存活时间比较长,存活率标记高 。
永久代(Permanet Generation)的回收算法
用于存放静态文件,如Java类、方法等 。永久代对垃圾回收没有显著影响,但是有些应用可能动态生成或者调用一些class,例如Hibernate 等,在这种时候需要设置一个比较大的永久代空间来存放这些运行过程中新增的类 。永久代也称方法区 。方法区主要回收的内容有:废弃常量和无用的类 。对于废弃常量也可通过根搜索算法来判断,但是对于无用的类则需要同时满足下面3个条件:
  • 该类所有的实例都已经被回收,也就是Java堆中不存在该类的任何实例;
  • 加载该类的ClassLoader已经被回收;
  • 该类对应的java.lang.Class对象没有在任何地方被引用,无法在任何地方通过反射访问该类的方法 。
3.4.4 垃圾收集器
  1. Serial收集器(复制算法)
新生代单线程收集器,标记和清理都是单线程,优点是简单高效 。是client级别默认的GC方式,可以通过-XX:+UseSerialGC来强制指定 。
  1. Serial Old收集器(标记-整理算法)
老年代单线程收集器,Serial收集器的老年代版本 。
  1. ParNew收集器(停止-复制算法)
新生代多线程收集器,其实就是Serial收集器的多线程版本,在多核CPU环境下有着比Serial更好的表现 。
  1. Parallel Scavenge收集器(停止-复制算法)
新生代并行的多线程收集器,追求高吞吐量,高效利用CPU 。吞吐量一般为99%,吞吐量= 用户线程时间/(用户线程时间+GC线程时间) 。适合后台应用等对交互相应要求不高的场景 。是server级别默认采用的GC方式,可用-XX:+UseParallelGC来强制指定,用-XX:ParallelGCThreads=4来指定线程数 。
  1. Parallel Old收集器(停止-复制算法)
老年代并行的多线程收集器,Parallel Scavenge收集器的老年代版本,并行收集器,吞吐量优先 。
  1. CMS(Concurrent Mark Sweep)收集器(标记-清除算法)
CMS收集器是一种以获取最短回收停顿时间为目标的收集器,CMS收集器是基于“标记--清除”(Mark-Sweep)算法实现的,整个过程分为四个步骤: