最大堆和初始堆的设置
package com.liuyao;
/**
* Created By liuyao on 2018/4/6 10:39.
*/
public class HeapAlloc {
public static void main(String[] args) {
System.out.print("MaxMemory=");
System.out.println(Runtime.getRuntime().maxMemory()+" bytes");
System.out.print("free mem=");
System.out.println(Runtime.getRuntime().freeMemory()/1024.0/1024.0+" M");
System.out.print("total mem=");
System.out.println(Runtime.getRuntime().totalMemory()/1024.0/1024.0+" M");
byte[] b=new byte[1*1024*1024];
System.out.println("分配了1M空间");
System.out.print("MaxMemory=");
System.out.println(Runtime.getRuntime().maxMemory()+" M");
System.out.print("free mem=");
System.out.println(Runtime.getRuntime().freeMemory()/1024.0/1024.0+" M");
System.out.print("total mem=");
System.out.println(Runtime.getRuntime().totalMemory()/1024.0/1024.0+" M");
b=new byte[4*1024*1024];
System.out.println("分配了4M空间");
System.out.print("MaxMemory=");
System.out.println(Runtime.getRuntime().maxMemory()+" M");
System.out.print("free mem=");
System.out.println(Runtime.getRuntime().freeMemory()/1024.0/1024.0+" M");
System.out.print("total mem=");
System.out.println(Runtime.getRuntime().totalMemory()/1024.0/1024.0+" M");
}
}
运行参数最大20M,初始化5M:
-Xmx20m -Xms5m -XX:+PrintCommandLineFlags -XX:+PrintGCDetails -XX:+UseSerialGC -Xloggc:gc.log
输出GC日志为:
实际工作中,也可以直接将初始堆-Xms与最大堆-Xmx设置相等,这样的好处是可以减少程序运行时进行垃圾回收的次数,从而提高程序性能
新生代设置
-Xmn
可以用于设置新生代的大小,较大的新生代会减小老年代的大小,这个参数对GC行为有很大影响,新生代大小一般设置为整个堆空间的1/3到1/4左右
-XX:SurvivorRatio
用来设置新生代中的eden空间和from/to空间的比例,即SurvivorRatio=eden/from=eden/to
package com.liuyao;
/**
* Created By liuyao on 2018/4/6 14:45.
*/
public class NewSizeDemo {
public static void main(String[] args) {
byte[] b=null;
//每次申请1M空间,一共申请10次
for (int i = 0; i < 10; i++) {
b=new byte[1*1024*1024];
}
}
}
运行参数:
-Xmx20m -Xms20m -Xmn1m -XX:SurvivorRatio=2 -XX:+PrintGCDetails -XX:+UseSerialGC
结果
运行参数2
-Xmx20m -Xms20m -Xmn7m -XX:SurvivorRatio=2 -XX:+PrintGCDetails -XX:+UseSerialGC -XX:+PrintCommandLineFlags
结果
运行参数3:
-Xmx20m -Xms20m -Xmn15m -XX:SurvivorRatio=2 -XX:+PrintGCDetails -XX:+UseSerialGC -XX:+PrintCommandLineFlags
结果
不同的堆分布情况,堆系统执行有一定影响,故尽可能将对象预留在新生代 即分配一个较大的新生代,减少老年代的GC次数,像第一种情况,把对象都分配在老年代,会提取触发老年代GC
-XX:NewRatio=老年代/新生代
指定老年代和新生代的比例
运行参数:
-Xmx20m -Xms20m -XX:NewRatio=2 -XX:+PrintGCDetails -XX:+UseSerialGC -XX:+PrintCommandLineFlags
结果
注意
如果上诉运行的参数为:
-Xmx20m -Xms20m -Xmn1m -XX:SurvivorRatio=2 -XX:+PrintGCDetails -XX:+PrintCommandLineFlags
即没有使用SerialGC,那么运行的结果为:
图中不是def New generation
而是PSYoungGen
这是因为:
DefNew :
-XX:UseSerialGC
(新生代和老年代都使用串行回收收集器)ParNew:
-XX:UseParNewGC
(新生代使用并行收集器,老年代使用串行收集器)或者-XX:+UseConcMarkSweepGC
(新生代使用并行收集器,老年代使用CMS)PSYoungGen:
-XX:UseParallelOldGC
(新生代,老年代都使用并行收集器)或者-XX:UseParallelGC
(新生代使用并行,老年代使用串行)garbage-first heap :
-XX:+UseG1GC
(使用G1收集器)
而eden和from的比例也不是2而是1,这是因为在HotSpot VM里,并行系的收集器(UseParallelGC / UseParallelOldGC)默认开启-XX:+UseAdaptiveSizePolicy, 这个配置会在每次Minor GC之后对From和To区进行自适应分配大小,而SurvivorRatio使用默认值8,设置成任何非8的数值都会无效。
如果既想用ParallelScavenge收集器,又想自己按照应用特点来设置From和To区大小,需要手动添加:-XX:-UseAdaptiveSizePolicy
方法区设置
在JDK1.6和1.7中可以使用-XX:Permsize
和-XX:MaxPermSize
配置持久区的初始大小和最大的大小
在JDK1.8中永久区被移除了,使用了新的元数据区存放类的元数据。默认情况下,元数据区只受可用内存大小的限制,但可以使用-XX:MaxMetaspaceSize
指定永久区最大可用值。
栈配置
-Xss
用来指定线程最大的栈空间,也直接决定了函数调用的最大深度
直接内存配置
直接内存跳过了Java堆,使Java程序可以直接访问原生堆空间,因此,从一定程度上加快了内存空间的访问速度。
-XX:MaxDirectMemorySize
最大可用直接内存,如不设置,默认为最大的堆空间即-Xmx
Server/Client 工作模式
-client
: 指定虚拟机使用Client模式
-server
:指定虚拟机使用server模式
与Client模式相比,Server模式启动更慢,因为Server模式会尝试收集更多的系统性能信息,使用更复杂的优化算法对程序进行优化。因此当系统完全启动后并进入稳定运行时,Server模式的执行速度回远远快于CLient模式。
Server模式适合后台长期运行的系统,而Client模式适合用户界面程序,运行时间不长,但要求启动快。
-XX:+PrintFlagsFinal
查看各模式下的各种参数。