常见虚拟机配置
标签:JVM

常见虚拟机配置

最大堆和初始堆的设置

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这是因为:

  1. DefNew :-XX:UseSerialGC(新生代和老年代都使用串行回收收集器)

  2. ParNew:-XX:UseParNewGC(新生代使用并行收集器,老年代使用串行收集器)或者-XX:+UseConcMarkSweepGC(新生代使用并行收集器,老年代使用CMS)

  3. PSYoungGen:-XX:UseParallelOldGC(新生代,老年代都使用并行收集器)或者-XX:UseParallelGC(新生代使用并行,老年代使用串行)

  4. 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

一个由-XX:SurvivorRatio失效引发的探索

方法区设置

在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 查看各模式下的各种参数。

  • 6 min read

CONTRIBUTORS


  • 6 min read