jvm学习记录--03 jvm参数配置

来源:互联网 发布:哪家4g网络好 编辑:程序博客网 时间:2024/05/19 17:08

前言

通过虚拟机参数可以对虚拟机进行设置(如设置堆大小,栈深度等),可以对虚拟机进行跟踪(跟踪垃圾回收信息,类加载情况)。
通过对虚拟机参数的设置来解决诊断问题与性能优化。

参数的使用有三种

-XX:+<option> 开启参数-XX:-<option> 关闭参数-XX:<option>=<value> 将option参数的值设置为value

跟踪Java虚拟机垃圾回收

-XX:+PrintGC

使用参数-XX:+PrintGC 启动Java虚拟机,只要有GC就会输出内容。
这里写图片描述

每一次GC就会输出一行内容,这里一共有4次GC。
第一次GC为例:GC之前堆可用空间大约4M,GC执行完毕之后可用空间377k,当前堆的总空间大约16M。执行这一次GC使用的时间为0.0006926秒

-XX:+PrintGCDetails

查看更详细的GC内容.

//jvm options -Xmx20M -Xms5M -XX:+PrintGCDetails -XX:+UseSerialGC//UseSerialGC 设置垃圾回收模式为串行的方式public class HeapVmOptions2 {    public static void main(String[] args) {        byte[] bt = new byte[1*1024*1024];        bt = new byte[4*1024*1024];    }}
[GC[DefNew: 622K->128K(1536K), 0.0017113 secs] 622K->464K(4992K), 0.0017395 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] [GC[DefNew: 1152K->0K(1536K), 0.0013924 secs][Tenured: 1488K->1488K(3456K), 0.0024423 secs] 1488K->1488K(4992K), [Perm : 2504K->2504K(21248K)], 0.0038614 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] Heap def new generation   total 1664K, used 92K [0x00000000f9a00000, 0x00000000f9bc0000, 0x00000000fa0a0000)  eden space 1536K,   6% used [0x00000000f9a00000, 0x00000000f9a171d8, 0x00000000f9b80000)  from space 128K,   0% used [0x00000000f9b80000, 0x00000000f9b80000, 0x00000000f9ba0000)  to   space 128K,   0% used [0x00000000f9ba0000, 0x00000000f9ba0000, 0x00000000f9bc0000) tenured generation   total 7556K, used 5584K [0x00000000fa0a0000, 0x00000000fa801000, 0x00000000fae00000)   the space 7556K,  73% used [0x00000000fa0a0000, 0x00000000fa6142f8, 0x00000000fa614400, 0x00000000fa801000) compacting perm gen  total 21248K, used 2513K [0x00000000fae00000, 0x00000000fc2c0000, 0x0000000100000000)   the space 21248K,  11% used [0x00000000fae00000, 0x00000000fb0747f8, 0x00000000fb074800, 0x00000000fc2c0000)No shared spaces configured.

可以看到类似这的内容,出现了新生代(DefNew),老年代(Tenured),永久区(Perm )的情况更加细致。

-Xloggc

输出GC日志到指定文件里面
例如:
输出详细GC内容到c盘 log.txt文件中

-XX:+PrintGCDetails -Xloggc:c:/log.txt

跟踪Java类加载/卸载

-XX:+TraceClassLoading

查看类的卸载

-XX:+TraceClassUnloading

查看类的加载

系统参数查看

Java虚拟机中有很多参数可以配置,不同的配置对Java虚拟机的执行效果有很大的影响。有时候有必要获取实际的运行参数,Java虚拟机提供了一些参数来获取这些运行时的实际值。

-XX:+PrintVMOptions

这里写图片描述
运行时传入参数,那么控制台就会输出

VM option '+PrintVMOptions'VM option '+PrintGC'

这个参数的作用就是输出启动时传给Java虚拟机的参数,但是这里只能打印出来显式的参数

-XX:+PrintCommandLineFlags

这里写图片描述
输出内容:

-XX:InitialHeapSize=133185408 -XX:MaxHeapSize=2130966528 -XX:+PrintCommandLineFlags -XX:+PrintGC -XX:+UseCompressedOops -XX:-UseLargePagesIndividualAllocation -XX:+UseParallelGC 

可以看到不仅仅有设置的PrintCommandLineFlags 和 PrintGC 还有一些其他没有设置的参数,这些是隐式参数也可输出

-XX:+PrintFlagsFinal

这个参数可以输出所有的系统信息,达到几百个之多。

Java堆的参数设置

最大值和最小值

public class HeapVmOptions {    public static void main(String[] args) {        //maxMemory : 表示Java虚拟机最多能从操作系统中使用的内存        //totalMemory : 表示java虚拟机现在已经从操作系统那里获取来的内存大小        //freeMemory : 表示java虚拟机现在已经从操作系统那里获取来的内存,然后又没有使用的大小。        System.out.println("Max Memory=" + Runtime.getRuntime().maxMemory() + " bytes");        System.out.println("Free Memory=" + Runtime.getRuntime().freeMemory() + " bytes");        System.out.println("Total Memory=" + Runtime.getRuntime().totalMemory() + " bytes");        byte[] bt = new byte[1*1024*1024];        System.out.println("分配了1M空间给数组");        System.out.println("Max Memory=" + Runtime.getRuntime().maxMemory() + " bytes");        System.out.println("Free Memory=" + Runtime.getRuntime().freeMemory() + " bytes");        System.out.println("Total Memory=" + Runtime.getRuntime().totalMemory() + " bytes");        bt = new byte[4*1024*1024];        System.out.println("分配了4M空间给数组");        System.out.println("Max Memory=" + Runtime.getRuntime().maxMemory() + " bytes");        System.out.println("Free Memory=" + Runtime.getRuntime().freeMemory() + " bytes");        System.out.println("Total Memory=" + Runtime.getRuntime().totalMemory() + " bytes");        bt = null;        System.out.println("清空数组");        System.out.println("Max Memory=" + Runtime.getRuntime().maxMemory() + " bytes");        System.out.println("Free Memory=" + Runtime.getRuntime().freeMemory() + " bytes");        System.out.println("Total Memory=" + Runtime.getRuntime().totalMemory() + " bytes");    }}

运行参数:

-Xmx20M -Xms5M -XX:+PrintGCDetails -XX:+UseSerialGC

设置最大内存20M,最小内存5M,以串行化进行垃圾回收,打印垃圾回收详细信息
输出结果:

Max Memory=20316160 bytesFree Memory=4472600 bytesTotal Memory=5111808 bytes[GC[DefNew: 624K->128K(1536K), 0.0018178 secs] 624K->466K(4992K), 0.0018725 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 分配了1M空间给数组Max Memory=20316160 bytesFree Memory=3556768 bytesTotal Memory=5111808 bytes[GC[DefNew: 1180K->0K(1536K), 0.0014202 secs][Tenured: 1490K->1490K(3456K), 0.0024887 secs] 1518K->1490K(4992K), [Perm : 2505K->2505K(21248K)], 0.0039385 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 分配了4M空间给数组Max Memory=20316160 bytesFree Memory=3641424 bytesTotal Memory=9441280 bytes清空数组Max Memory=20316160 bytesFree Memory=3641424 bytesTotal Memory=9441280 bytesHeap def new generation   total 1664K, used 108K [0x00000000f9a00000, 0x00000000f9bc0000, 0x00000000fa0a0000)  eden space 1536K,   7% used [0x00000000f9a00000, 0x00000000f9a1b100, 0x00000000f9b80000)  from space 128K,   0% used [0x00000000f9b80000, 0x00000000f9b80000, 0x00000000f9ba0000)  to   space 128K,   0% used [0x00000000f9ba0000, 0x00000000f9ba0000, 0x00000000f9bc0000) tenured generation   total 7556K, used 5586K [0x00000000fa0a0000, 0x00000000fa801000, 0x00000000fae00000)   the space 7556K,  73% used [0x00000000fa0a0000, 0x00000000fa6149f8, 0x00000000fa614a00, 0x00000000fa801000) compacting perm gen  total 21248K, used 2515K [0x00000000fae00000, 0x00000000fc2c0000, 0x0000000100000000)   the space 21248K,  11% used [0x00000000fae00000, 0x00000000fb074e98, 0x00000000fb075000, 0x00000000fc2c0000)

说明:

这里设置的最大可用为20M ,

-Xmn

Java堆里面存储的是对象,对象按照垃圾回收来划分的话,区分为新生代,老年代,永久区。

设置的新生代的绝对大小,设置一个较大的新生代会让老年代减小,新生代的大小一般设置在堆大小的3分之一或者4分之一

-XX:NewRatio

设置新生代与老年代的大小比例, -XX:NewRatio=2 ,那么新生代的大小是老年代的2倍

-XX:SurvivorRatio=2

设置新生代中eden空间与from/to空间大小比例,这里设置eden的空间是from/to的两倍

设置参数: -Xmn1M -XX:SurvivorRatio=2 

输出如下:新生代总空间1M,eden512k,from/to正好是一半256k,

Heap def new generation   total 768K, used 39K [0x00000000f9a00000, 0x00000000f9b00000, 0x00000000f9b00000)  eden space 512K,   7% used [0x00000000f9a00000, 0x00000000f9a09fc8, 0x00000000f9a80000)  from space 256K,   0% used [0x00000000f9a80000, 0x00000000f9a80000, 0x00000000f9ac0000)  to   space 256K,   0% used [0x00000000f9ac0000, 0x00000000f9ac0000, 0x00000000f9b00000)

堆信息导出

堆溢出的时候导出信息到d盘1.dump文件中

import java.util.LinkedList;import java.util.List;public class HeapOfMenory {    public static void main(String[] args) {        List<byte[]> list = new LinkedList<byte[]>();        while(true){            byte[] bt = new byte[1*1024*1024];            list.add(bt);        }    }}

参数

-Xmx20M -Xms5M -XX:+PrintGCDetails -XX:+UseSerialGC -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=d:/1.dump

输出(可以发现导出文件已经生产)

java.lang.OutOfMemoryError: Java heap spaceDumping heap to d:/1.dump ...Heap dump file created [18946569 bytes in 0.019 secs]Exception in thread "main" java.lang.OutOfMemoryError: Java heap space

方法区配置

在1.6和1.7版本的Hotspot版本虚拟机中通过 -XX:PermSize-XX:MaxPermSize设置最小值和最大值.
在1.8版本的Hotspot虚拟机中通过-XX:MaxMetaspaceSize来设置最大值

栈配置

通过-Xss配置每个线程的栈大小

直接内存配置

最大可用直接内存可用通过参数-XX:MaxDirectMemorySize来设置,默认值是最大的堆空间。当直接内存使用达到最大值,就会触发垃圾回收,如果无法回收就会抛出异常内存溢出.

虚拟机的工作模式Client和Server

Java虚拟机有两种工作模式Client和Server。
Server适用于长期稳定运行的系统,它启动会收集更多的系统信息,启动会慢。
Client启动比较快,适用于运行时间不长,需要马上启动的系统。

通过Java -version 可以看到当前的Java虚拟机启动模式。

可以通过 -client 和 -server 来设置Java虚拟机的启动模式