jvm调优垃圾回收
JVM垃圾回收算法
两个概念:
新生代:存放生命周期较短的对象的区域。(年轻的)
老年代:存放生命周期较长的对象的区域。(年老的)
GC算法:
1.Mark-Sweep(标记清除算法)
标记:遍历内存区域,对需要回收的对象打上标记。
清除:再次遍历内存,对已经标记过的内存进行回收。
图解说明:
缺点:
效率问题;遍历了两次内存空间(第一次标记,第二次清除)。
空间问题:容易产生大量内存碎片,当再需要一块比较大的内存时,无法找到一块满足要求的,因而不得不再次出发GC。
2.Copying(拷贝算法)
将内存划分为等大的两块,每次只使用其中的一块。当一块用完了,触发GC时,将该块中存活的对象复制到另一块区域,然后一次性清理掉这块没有用的内存。下次触发GC时将那块中存活的的又复制到这块,然后抹掉那块,循环往复。这样速度很快,在新生代区域使用的就是拷贝算法,这样速度很快。
缺点:内存利用率不高,每次只能使用一半内存。
图解说明:
3.Mark-Compact(标记压缩算法)
优点:既不浪费内存也不会产生碎片
步骤:将需要回收的垃圾进行标记,然后让有用的部分向一端移动将移动后空出的部分进行回收,需要一边清理垃圾一边压缩垃圾。速度上来说会慢一些
图解说明:
十种垃圾回收器: 分代模型:ParNew、CMS、Serial、SerialOld、ParallelScavenge(PS)、ParallelOld 不分代模型:G1、ZGC、Shenandoah 特殊模型:Epsilon
在年轻代使用的:ParNew、Serial、ParallelScavenge 在年老的时候使用:CMS、SerialOld、ParallelOld
配对使用:
1.ParNew、CMS
2。Serial、CMS
3.ParallelScavenge、SerialOld
4.ParallelScavenge、ParallelOld
5。Serial、SerialOld
6.ParNew、SerialOld
最常用的组合方式
1.ParNew、CMS
2.Serial、SerialOld
3.ParallelScavenge、ParallelOld
jdk1.8默认ParallelScavenge和ParallelOld回收器
分代的讲解:
新生代:刚刚new出来的对象,没有经历过垃圾回收。新生代很容易被回收掉(采用拷贝算法速度很快)
在新生代中的拷贝算法的说明:将新生代分为三个部分比例我为8:1:1,分别是eden(伊甸)、survior(幸存区)将刚刚new出来的对象放入到eden中,一次垃圾回收时将有用的对象拷贝到survior中然后将eden中的所有对象进行回收,这样速度会很快。如果第二次回收时eden中存在有用的对象那么就复制到第二个survivor中,如果第一个survivor中对象还有用那么就将第一个survivor中的对象复制到第二个survivor中,然后将eden和第一个survivor全部都回收掉。如果再下一次那么将eden中有用的放入到第一个survivor中,把第二个survivor中有用的也放入到第一个中,然后将第二个survivor和eden中的对象全部回收。(后续依然像这个顺序一样先放入到第一个survivor第二次再放入到第二个,将没有用对象的区域全部回收掉,等着对象到了一定的时间即年龄后会被放入到老年代中,算法会发生变化,下面解释算法)
老年代:垃圾回收多次没有被回收的被放入到老年代(标记清除算法或者标记压缩算法)
老年代会很长时间才会被回收一次所有速度上没有要求,老年代回收是开满了的时候才会触发垃圾回收。
当new一个对象时首先尝试在栈上分配,如果可以分配那么就不用进行垃圾回收,栈会自动进行清理
当不能够在栈上分配时并且占用很大超过伊甸的剩余空间才会进入到老年代,老年代经过回收器进行回收
当不够大时会在线程本地进行分配到伊甸中,然后进行回收,多次不能回收的再进入到老年代中,让老年代进行回收
进入老年代的年龄CMS默认6岁,其余默认是15岁。可以自己进行设定