zoukankan      html  css  js  c++  java
  • JVM虚拟机(三):参数配置

    在虚拟机运行的过程中,如果可以跟踪系统的运行状态,那么对于问题的故障排查会有一定的帮助,为此,虚拟机提供了一些跟踪系统状态的参数,使用给顶的参数执行java虚拟机,就可以在系统运行时打印相关日志,用于分析实际问题。我们进行迅疾参数配置,其实主要是围绕着堆、栈、方法区进行配置。

    堆分配参数

    -XX:+PrintGC使用这个参数,虚拟机启动后,只要遇到GC就会打印日志。

    -XX:+UserSerialGC 配置串行回收器

    -XX:+PrintGCDetails可以查看详细信息,包括各个区的情况

    -Xms:设置java程序启动时初始堆大小

    -Xmx:设置java程序能获得的最大堆大小

    -Xmx20m -Xms5m -XX:+PringCommandLineFlags:可以将隐式或者显示传给虚拟机的参数输出

    package com.base001;
     
     
    public class Test01 {
     
        public static void main(String[] args) {
     
            //-Xms5m -Xmx20m -XX:+PrintGCDetails -XX:+UseSerialGC -XX:+PrintCommandLineFlags
            
            //查看GC信息
            System.out.println("max memory:" + Runtime.getRuntime().maxMemory());
            System.out.println("free memory:" + Runtime.getRuntime().freeMemory());
            System.out.println("total memory:" + Runtime.getRuntime().totalMemory());
            
            byte[] b1 = new byte[1*1024*1024];
            System.out.println("分配了1M");
            System.out.println("max memory:" + Runtime.getRuntime().maxMemory());
            System.out.println("free memory:" + Runtime.getRuntime().freeMemory());
            System.out.println("total memory:" + Runtime.getRuntime().totalMemory());
            
            byte[] b2 = new byte[4*1024*1024];
            System.out.println("分配了4M");
            System.out.println("max memory:" + Runtime.getRuntime().maxMemory());
            System.out.println("free memory:" + Runtime.getRuntime().freeMemory());
            System.out.println("total memory:" + Runtime.getRuntime().totalMemory());
            
        }
        
    }

    点击右键Run As,再点击Run configurations找到Arguments

    这是给主函数传递一些参数,我们需要的是第二个VM arguments

    往里面添加以下参数

    -Xms5m  -Xmx20m -XX:+PrintGCDetails -XX:+UseSerialGC 

    分配5m的初始化大小 最大的大小为20m 打印GC详细信息 使用串行的垃圾回收器 

    运行代码控制台出现:


    总结:在实际工作中,我们可以直接将初始的堆大小与最大堆大小设置相等,这样的好处是可以减少程序运行时的垃圾回收次数,从而提高性能。实际工作中一般这些参数都是配置到web容器或者tomcat中的。

    注意:-XX开头的一般都是设置jvm的参数,其它开头的都是设置具体工程的参数。

    堆里新生代的分配

    -Xmn:可以设置新生代的大小,设置一个比较大的新生代会减少老年代的大小,这个参数对系统性能以及GC行为有很大的影响,新生代大小一般会设置整个堆空间的1/3到1/4左右。

    -XX:SURvivorRatio:用来设置新生代中eden空间和from/to空间的比例。含义:-XX:SurvivorRatio=eden/from=eden/to

    package com.base001;
     
    public class Test02 {
     
        public static void main(String[] args) {
            
            //第一次配置
            //-Xms20m -Xmx20m -Xmn1m -XX:SurvivorRatio=2 -XX:+PrintGCDetails -XX:+UseSerialGC
            
            //第二次配置
            //-Xms20m -Xmx20m -Xmn7m -XX:SurvivorRatio=2 -XX:+PrintGCDetails -XX:+UseSerialGC
            
            //第三次配置
            //-XX:NewRatio=老年代/新生代
            //-Xms20m -Xmx20m -XX:SurvivorRatio=2 -XX:+PrintGCDetails -XX:+UseSerialGC
            
            byte[] b = null;
            //连续向系统申请10MB空间
            for(int i = 0 ; i <10; i ++){
                b = new byte[1*1024*1024];
            }
        }
    }

    第一次配置

    第二次配置

     

    第三次配置

    新生代和老年代的比例是1/2,新生代占一份,老生代占2份。

    总结:不同的对分布情况,对系统执行会产生一定的影响,在实际工作中应该根据系统的特点作出合理的配置,基本策略:尽可能将对象预留在新生代,减少老年代的GC次数。

    除了可以设置新生代的绝对大小(-Xmn),还可以使用(-XX:NewRatio)设置新生代和老年代的比例:-XX:NewRatio=老年代/新生代

    堆溢出处理

    在java程序的运行过程中,如果堆空间不足,则会抛出内存溢出的错误(Out Of Menory)OOM,一旦这类问题发生在生产环境,可能引起严重的业务中断,java虚拟机提供了-XX:+HeapDumpOnOutOfMemoryError,使用该参数可以在内存溢出是导出整个堆信息,与之配合使用的还有参数,-XX:HeapDumpPath,可以设置到处堆得存放路径。

    内存分析工具:Memory Analyzer 1.5.0

    地址:http://download.eclipse.org/mat/1.5/update-site/

    package com.base001;
     
    import java.util.Vector;
     
    public class Test03 {
     
        public static void main(String[] args) {
            
            //-Xms2m -Xmx1m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=d:/Test03.dump
            //堆内存溢出
            Vector v = new Vector();
            for(int i=0; i < 5; i ++){
                v.add(new Byte[1*1024*1024]);
            }
            
        }
    }

    添加参数

    运行后的结果

    存放到D盘下的异常文件。

    栈配置

    Java虚拟机提供了参数-Xss来制定线程的最大栈空间,整个参数也直接决定了函数课调用的最大深度。

    package com.base001;
     
    public class Test04 {
     
        //-Xss1m  
        //-Xss5m
        
        //栈调用深度
        private static int count;
        
        public static void recursion(){
            count++;
            recursion();
        }
        public static void main(String[] args){
            try {
                recursion();
            } catch (Throwable t) {
                System.out.println("调用最大深入:" + count);
                t.printStackTrace();
            }
        }
    }

    添加参数

    运行结果:

     方法区

    和java堆一样,方法区是一块所有线程共享的内存区域,它用于保存系统的类信息,方法区(永久区)可以保存多少信息可以对其进行配置,在默认情况下,-XX:MaxPermSize为64M,如果系统运行时产生大量的类,就需要设置一个相对合适的方法区,以免出现永久区内存溢出的问题。

    -XX:PermSize=64M -XX:MaxPermSize=64M
  • 相关阅读:
    一篇文章读懂JSON
    不该被忽视的CoreJava细节(四)
    Java面试题总结(二)
    Java面试题总结(一)
    不该被忽视的CoreJava细节(三)
    不该被忽视的CoreJava细节(一)
    逐步解读String类(一)
    JSP注释格式
    命令行启动mysql服务
    经典进程的同步问题之——生产者&&消费者
  • 原文地址:https://www.cnblogs.com/shamo89/p/9806718.html
Copyright © 2011-2022 走看看