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

扫描二维码关注公众号,回复: 2287092 查看本文章

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

往里面添加以下参数

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

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

运行代码控制台出现:



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

 

堆分配参数(二)


新生代的分配

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

-XXSURvivorRatio:用来设置新生代中eden空间和from/to空间的比例。含义:-XXSurvivorRatio=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,还可以使用(-XXNewRatio)设置新生代和老年代的比例:-XXNewRatio=老年代/新生代

堆溢出处理

 

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

内存分析工具:Memory Analyzer 1.5.0

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

Test03.java
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来制定线程的最大栈空间,整个参数也直接决定了函数课调用的最大深度。

Test04.java
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:MaxPermSize64M,如果系统运行时产生大量的类,就需要设置一个相对合适的方法区,以免出现永久区内存溢出的问题。

-XX:PermSize=64M -XX:MaxPermSize=64M

猜你喜欢

转载自blog.csdn.net/qq_32230309/article/details/80909112
今日推荐