原理:根据垃圾回收机制的不一样,Java堆有可能拥有不一样的结构,最为常见的就是将整个Java堆分为新生代和老年代。其中新生代存放新生的对象或者年龄不大的对象,老年代则存放老年对象。新生代分为eden区、s0区、s1区,s0和s1也被称为from和to区域,他们是两块大小相等而且能够互换角色的空间。绝大多数状况下,对象首先分配在eden区,在新生代回收后,若是对象还存活,则进入s0或s1区,以后每通过一次新生代回收,若是对象存活则它的年龄就加1,对象达到必定的年龄后,则进入老年代。算法
新生代:刚new出来不久的对象,不常常使用 会被优先回收 为堆内存的1/3或者1/4,采用复制算法实现
老年代:常常被使用的对象。使用15次后就会放入老年代中 比新生代优先级低 不会优先回收 若是老年代也不常常使用也会被回收,采用标记压缩算法(也叫标记整理算法)数组
即把内存分红相等的AB两块,每次只使用其中的一块。好比当A内存使用完后,就把A中还存活着的对象复制到另一块内存中去(B),而后再把已经使用过的内存清理掉。优势:这样就不用考虑内存碎片的问题了。缺点:内存减半,代价略高。优化
复制算法当存活的实例多的时候,就须要大量复制,效率不高,不适合老年代。那么就能够采用标记-整理算法。也就是先标记,而后对存活的对象进行移动,所有移动到一端,而后再对其它的内存进行清理。日志
设置新生代比例参数
参数: -Xms20m -Xmx20m -XX:SurvivorRatio=2 -XX:+PrintGCDetails -XX:+UseSerialGC -XX:NewRatio=2对象
堆的参数配置
-XX:+PrintGC 每次触发GC的时候打印相关日志
-XX:+UseSerialGC 串行回收
-XX:+PrintGCDetails 更详细的GC日志
-Xms 堆初始值
-Xmx 堆最大可用值
-Xmn 新生代堆最大可用值
-XX:SurvivorRatio 用来设置新生代中eden空间和from/to空间的比例.
含义:-XX:SurvivorRatio=eden/from=den/to
-XX:SurvivorRatio 用来设置新生代中eden空间和from/to空间的比例.生命周期
总结:在实际工做中,咱们能够直接将初始的堆大小与最大堆大小相等,
这样的好处是能够减小程序运行时垃圾回收次数,从而提升效率。内存
尽可能减小垃圾回收的次数,多了的话会影响效率
堆的初始值与堆内存的最大值要保持一致
初始值越小,垃圾回收次数越多(生产环境上面初始值和最大值必定要一致)
针对JVM堆的设置,通常能够经过-Xms -Xmx限定其最小、最大值,
(1)为了防止垃圾收集器在最小、最大之间收缩堆而产生额外的时间,咱们一般把最大、最小设置为相同的值
(2)年轻代和年老代将根据默认的比例(1:2)分配堆内存,能够经过调整两者之间的比率NewRadio来调整两者之间的大小,
也能够针对回收代,好比年轻代,经过 -XX:newSize -XX:MaxNewSize来设置其绝对大小。
一样,为了防止年轻代的堆收缩,咱们一般会把-XX:newSize -XX:MaxNewSize设置为一样大小字符串
GC(或Minor GC):收集生命周期短的区域(Young area)。io
Full GC (或Major GC):收集生命周期短的区域(Young area)和生命周期比较长的区域(Old area)对整个堆进行垃圾收集。效率
他们的收集算法不一样,因此使用的时间也不一样。
Minor GC后,Eden是空的吗?
是的,Minor GC会把Eden中的全部存活对象都移到Survivor区域中,若是Survivor区中放不下,那么剩下的存活对象就被移到Old generation 中。
GC 效率也会比较高,咱们要尽可能减小 Full GC 的次数。 当显示调用System.gc() 时,gc does a full collection(both young generation and tenured generation).
显式调用system.gc()会触发full gc,对象在Eden出生每经历一次MInor GC后仍然存活,而且能被Survivor容纳,就会被移动到Survivor,
并设定年龄为1.之后在Survivor每"熬过"一次Minor GC,年龄就增长一岁,当年龄超过必定值(15次)就被移动到老年代,MaxTenuringThreshold用于设置年龄阈值,可是若是Survivor空间中相同年龄全部对象大小的总和大于Survivor空间的一半,
年龄大于或等于该年龄的对象就能够直接进入老年代,无须等到MaxTenuringThreshold中要求的年龄。
大对象直接进入老年代,好比长数组或长字符串,-XX:PretenureSizeThreshold用于设置大于这个值直接在老年代分配。