堆的分配参数:
-Xmx //设立最大堆
-Xms //最小堆,初始化堆大小
-Xmn //设置新生代(eden+2*surviivor+old)大小 官方推荐:3/8Xmx------》感觉就是-XX:NewRatio 2到3之间
-XX:NewRatio //新生代(eden+2*s)和老年代(不包含永久区,永久区是非堆)的比值 2表示 新生代:老年代=1:2,即年轻代占堆的1/3,一般来说,老年代占比较多
-XX:SurvivorRatio //8 表示 (两个)Survivor :eden=2:8,即一个Survivor占年轻代的1/10(官方推荐比例),当eden区满了,就回触发垃圾回收
示例:新生代(def new generation)与老年代(tenured)的比例1:1,各占10M左右
通过调节eden区(SurvivorRatio)的大小,减少gc次数 ,会影响新生代晋升老年代 。 这里老年代的话,一种是分配担保,一种是GC次数多了,可能会回收新生代的大年龄引用
在OOM时,记得Dump出堆,确保可以排查现场问题,不然难以复现
-XX:+HeapDumpOnOutOfMemoryError OOM时导出堆到文件
-XX:OnOutOfMemoryError 在OOM时,执行一个脚本,可以报警,发送邮件
-XX:+HeapDumpPath 导出OOM的路径
-Xmx20m -Xms5m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=d:/a.dump
Vector v=new Vector();
for(int i=0;i<25;i++)
v.add(new byte[1*1024*1024]);
//总共18.8M,每一个节点占据1.048M
栈大小分配
-Xss 通常只有几百K(1M已经很够了) 决定了函数调用的深度 每个线程都有独立的栈空间 局部变量、参数 分配在栈上
一般来说,方法的递归调用,会出现函数调用的深度过深,导致java.lang.StackOverflowError