众所周知,GC主要回收的是堆内存,堆内存中包含年轻代和老年代,年轻代分为Eden和Surivor,以下图所示。咱们用案例分析下堆的GC信息【版本:HotSpot JDK1.8】。java
/** * @author :jiaolian * @date :Created in 2021-03-15 15:02 * @description:新生代内存测试 * @modified By: * 公众号:叫练 */ public class NewGenTest { public static void main(String[] args) { //每次在Eden申请1M空间 byte[] bytes = null; for (int i=0; i<5; i++) { bytes = new byte[1024*1024]; } } }
案例很简单,for循环运行5次,每次在Eden申请1M空间,假设咱们分配堆内存空间是20m,并打印GC详细信息,配置过程:-XX:+PrintGCDetails -Xmx20m。微信
运行程序,IDEA控制台打印结果以下:ide
上面程序不变,设置JVM参数,-XX:+PrintGCDetails -Xmx20m -Xms5m,运行程序,部分结果以下图所示。学习
如上图所示:初始化堆大小是5M,新生代内存一共发生了4次GC,从上图能够分析,Eden只有1M多内存能够被申请,因此第二次for循环申请1M空间就触发了GC,数据就被丢进老年代,连续3次后,GC堆的空间由5M变为了6M,说明初始化堆空间不够使,能够自动扩展堆内存。测试
固然咱们还能够经过-Xmn 设置年轻代大小。下面咱们看看年轻代中,Eden和from/to区域怎么划分。spa
上面程序不变,设置JVM参数,-XX:+PrintGCDetails -Xmx20m -Xmn10m -XX:SurvivorRatio=2,运行程序,部分结果以下图所示。3d
咱们设置新生代是10M,这里显示新生代大小是7.5M(7680K),实际上from/to是有一块空间是每次GC作交换的区域(方便垃圾回收),因此实际上7680K=5120+2560。5120/2560=2,也就是新生代和和Survivor空间比例。blog
另外还有:-XX:NewRatio:设置老年代和新生代比例,通常是1/3)。好比设置-XX:NewRatio=2 -XX:+PrintGCDetails -Xmx30mip
那么老年代空间是20M,新生代空间是10M。内存
最后总结下:
今天学习了JVM之GC信息参数配置,写的不全同时还有许多须要修正的地方,但愿亲们加以指正和点评,喜欢的请点赞加关注哦。点关注,不迷路,我是【叫练】公众号,微信号【jiaolian123abc】边叫边练。