JVM故障诊断与性能优化--jvm参数了解(二)

跟踪垃圾回收和类加载信息

1.跟踪垃圾回收

示例---读懂日志:

package chapter3;

/**
 * 创建实例,演示垃圾回收,进行4次minorGC
 * 
 * @author shiker 
 * 预设参数:-verbose:gc -Xms20M -Xmx20M(设置堆容量为20M) -Xmn10M(新生代容量10M) -XX:SurvivorRatio=8(survivor占比8:1)
 *         -XX:+UseSerialGC(串行收集)
 */
public class GC {

	private final static int _1MB = 1024 * 1024;

	public static void allocation() {
		byte[] allocation1, allocation2, allocation3, allocation4, allocation5;
		allocation1 = new byte[6 * _1MB];
		allocation1 = null;
		allocation2 = new byte[6 * _1MB];
		allocation2 = null;
		allocation3 = new byte[6 * _1MB];
		allocation3 = null;
		allocation4 = new byte[6 * _1MB];
		allocation4 = null;
		allocation5 = new byte[6 * _1MB];
	}

	public static void main(String[] args) {
		allocation();
	}
}

打印GC日志:-XX:+PrintGC

[GC 6980K->464K(19456K), 0.0016742 secs]

[GC 6692K->464K(19456K), 0.0011463 secs]

[GC 6608K->464K(19456K), 0.0014733 secs]

[GC 6608K->464K(19456K), 0.0010629 secs]

打印详细GC信息:-XX:+PrintGCDetails

[GC[DefNew: 6980K->464K(9216K), 0.0022013 secs] 6980K->464K(19456K), 0.0022530 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]

[GC[DefNew: 6692K->464K(9216K), 0.0013325 secs] 6692K->464K(19456K), 0.0013612 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]

[GC[DefNew: 6608K->464K(9216K), 0.0010149 secs] 6608K->464K(19456K), 0.0010433 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]

[GC[DefNew: 6608K->464K(9216K), 0.0010282 secs] 6608K->464K(19456K), 0.0010542 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]

Heap

 def new generation   total 9216K, used 6772K [0x00000000f9a00000, 0x00000000fa400000, 0x00000000fa400000)

  eden space 8192K,  77% used [0x00000000f9a00000, 0x00000000fa028fd0, 0x00000000fa200000)

  from space 1024K,  45% used [0x00000000fa200000, 0x00000000fa274250, 0x00000000fa300000)

  to   space 1024K,   0% used [0x00000000fa300000, 0x00000000fa300000, 0x00000000fa400000)

 tenured generation   total 10240K, used 0K [0x00000000fa400000, 0x00000000fae00000, 0x00000000fae00000)

   the space 10240K,   0% used [0x00000000fa400000, 0x00000000fa400000, 0x00000000fa400200, 0x00000000fae00000)

 compacting perm gen  total 21248K, used 2569K [0x00000000fae00000, 0x00000000fc2c0000, 0x0000000100000000)

   the space 21248K,  12% used [0x00000000fae00000, 0x00000000fb0826d8, 0x00000000fb082800, 0x00000000fc2c0000)

No shared spaces configured.

打印详细堆信息:-XX:+PrintHeapAtGC

{Heap before GC invocations=0 (full 0):

 def new generation   total 9216K, used 6980K [0x00000000f9a00000, 0x00000000fa400000, 0x00000000fa400000)

  eden space 8192K,  85% used [0x00000000f9a00000, 0x00000000fa0d1018, 0x00000000fa200000)

  from space 1024K,   0% used [0x00000000fa200000, 0x00000000fa200000, 0x00000000fa300000)

  to   space 1024K,   0% used [0x00000000fa300000, 0x00000000fa300000, 0x00000000fa400000)

 tenured generation   total 10240K, used 0K [0x00000000fa400000, 0x00000000fae00000, 0x00000000fae00000)

   the space 10240K,   0% used [0x00000000fa400000, 0x00000000fa400000, 0x00000000fa400200, 0x00000000fae00000)

 compacting perm gen  total 21248K, used 2562K [0x00000000fae00000, 0x00000000fc2c0000, 0x0000000100000000)

   the space 21248K,  12% used [0x00000000fae00000, 0x00000000fb080b78, 0x00000000fb080c00, 0x00000000fc2c0000)

No shared spaces configured.

[GC 6980K->464K(19456K), 0.0016602 secs]

{Heap after GC invocations=1 (full 0):

 def new generation total 9216K, used 464K [0x00000000f9a00000, 0x00000000fa400000, 0x00000000fa400000)

  eden space 8192K, 0% used [0x00000000f9a00000, 0x00000000f9a00000, 0x00000000fa200000)

  from space 1024K, 45% used [0x00000000fa300000, 0x00000000fa3743b0, 0x00000000fa400000)

  to space 1024K, 0% used [0x00000000fa200000, 0x00000000fa200000, 0x00000000fa300000)

 tenured generation total 10240K, used 0K [0x00000000fa400000, 0x00000000fae00000, 0x00000000fae00000)

  the space 10240K, 0% used [0x00000000fa400000, 0x00000000fa400000, 0x00000000fa400200, 0x00000000fae00000)

 compacting perm gen total 21248K, used 2562K [0x00000000fae00000, 0x00000000fc2c0000, 0x0000000100000000)

  the space 21248K, 12% used [0x00000000fae00000, 0x00000000fb080b78, 0x00000000fb080c00, 0x00000000fc2c0000)

  No shared spaces configured.}

......

输出GC发生时间:-XX:+PrintGCTimeStamps

0.071: [GC 6980K->464K(19456K), 0.0017682 secs]

0.073: [GC 6692K->464K(19456K), 0.0014899 secs]

0.075: [GC 6608K->464K(19456K), 0.0010478 secs]

0.077: [GC 6608K->464K(19456K), 0.0010282 secs]

 

输出程序执行时间:-XX:+PrintGCApplicationConcurrentTime

Application time: 0.0091174 seconds

[GC 6980K->464K(19456K), 0.0020680 secs]

Application time: 0.0005690 seconds

[GC 6692K->464K(19456K), 0.0013332 secs]

Application time: 0.0004063 seconds

[GC 6608K->464K(19456K), 0.0014189 secs]

Application time: 0.0004841 seconds

[GC 6608K->464K(19456K), 0.0010399 secs]

Application time: 0.0007438 seconds

输出程序中断时间:-XX:+PrintGCApplicationStoppedTime

[GC 6980K->464K(19456K), 0.0022372 secs]

Total time for which application threads were stopped: 0.0023833 seconds

[GC 6692K->464K(19456K), 0.0012826 secs]

Total time for which application threads were stopped: 0.0013857 seconds

[GC 6608K->464K(19456K), 0.0010334 secs]

Total time for which application threads were stopped: 0.0011176 seconds

[GC 6608K->464K(19456K), 0.0010463 secs]

Total time for which application threads were stopped: 0.0011282 seconds

打印程序日志:-Xloggc:log/gc.log


2.类的加载/卸载跟踪

示例2---类的加载/卸载

package chapter3;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;

//继承classloader
public class UnloadClass extends ClassLoader implements Opcodes{
	public static void main(String[] args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {
		//定义一个叫做Example的类  
		ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS|ClassWriter.COMPUTE_FRAMES);
		cw.visit(Opcodes.V1_7,Opcodes.ACC_PUBLIC , "Example", null, "java/lang/Object", null);
		//生成默认构造方法
		MethodVisitor mw = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
		//生成构造方法的字节码指令
		mw.visitVarInsn(ALOAD, 0);
		mw.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V");
		mw.visitInsn(RETURN);
		mw.visitMaxs(1, 1);
		mw.visitEnd();
		//生成main方法
		mw = cw.visitMethod(ACC_PUBLIC+ACC_STATIC, "main", "([Ljava/lang/String;)V", null, null);
		//生成main方法中的字节码指令
		mw.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
		mw.visitLdcInsn("hello world");
		mw.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V");
		mw.visitInsn(RETURN);
		mw.visitMaxs(2, 2);
		//字节码生成完成
		mw.visitEnd();
		byte[] code = cw.toByteArray();
		for(int i=0;i<10;i++){
			UnloadClass loader = new UnloadClass();
			Method m = ClassLoader.class.getDeclaredMethod("defineClass", String.class,byte[].class,int.class,int.class);
			m.setAccessible(true);
			m.invoke(loader, "Example",code,0,code.length);
			//Class<?> exampleClass = loader.defineClass("Example", code, 0, code.length);  
			m.setAccessible(false);
			System.gc();
		}
	}

}

jvm参数设置:

-XX:+TraceClassUnloading(打印卸载日志)  -XX:+TraceClassLoading(打印加载日志)

输出结果:

...

[Loaded java.lang.SecurityException from D:\jre1.7\lib\rt.jar]
[Loaded java.lang.Void from D:\jre1.7\lib\rt.jar]
[Loaded org.objectweb.asm.ClassVisitor from file:/D:/program2015/jvm/src/org.objectweb.asm-3.2.0.jar]
[Loaded org.objectweb.asm.ClassWriter from file:/D:/program2015/jvm/src/org.objectweb.asm-3.2.0.jar]
[Loaded org.objectweb.asm.FieldVisitor from file:/D:/program2015/jvm/src/org.objectweb.asm-3.2.0.jar]
[Loaded org.objectweb.asm.AnnotationVisitor from file:/D:/program2015/jvm/src/org.objectweb.asm-3.2.0.jar]
[Loaded org.objectweb.asm.MethodVisitor from file:/D:/program2015/jvm/src/org.objectweb.asm-3.2.0.jar]
[Loaded org.objectweb.asm.ByteVector from file:/D:/program2015/jvm/src/org.objectweb.asm-3.2.0.jar]
[Loaded org.objectweb.asm.Item from file:/D:/program2015/jvm/src/org.objectweb.asm-3.2.0.jar]
[Loaded org.objectweb.asm.MethodWriter from file:/D:/program2015/jvm/src/org.objectweb.asm-3.2.0.jar]
[Loaded org.objectweb.asm.Type from file:/D:/program2015/jvm/src/org.objectweb.asm-3.2.0.jar]
[Loaded org.objectweb.asm.Label from file:/D:/program2015/jvm/src/org.objectweb.asm-3.2.0.jar]
[Loaded java.lang.IllegalStateException from D:\jre1.7\lib\rt.jar]
[Loaded org.objectweb.asm.Frame from file:/D:/program2015/jvm/src/org.objectweb.asm-3.2.0.jar]
[Loaded java.lang.ClassFormatError from D:\jre1.7\lib\rt.jar]
[Loaded java.io.IOException from D:\jre1.7\lib\rt.jar]
[Loaded java.lang.AssertionStatusDirectives from D:\jre1.7\lib\rt.jar]
[Loaded java.lang.Integer$IntegerCache from D:\jre1.7\lib\rt.jar]
[Loaded sun.reflect.NativeMethodAccessorImpl from D:\jre1.7\lib\rt.jar]
[Loaded sun.reflect.DelegatingMethodAccessorImpl from D:\jre1.7\lib\rt.jar]
[Loaded Example from __JVM_DefineClass__]
[Loaded Example from __JVM_DefineClass__]
[Unloading class Example]
[Loaded Example from __JVM_DefineClass__]
[Unloading class Example]
[Loaded Example from __JVM_DefineClass__]
[Unloading class Example]
[Loaded Example from __JVM_DefineClass__]
[Unloading class Example]
[Loaded Example from __JVM_DefineClass__]
[Unloading class Example]
[Loaded Example from __JVM_DefineClass__]
[Unloading class Example]
[Loaded Example from __JVM_DefineClass__]
[Unloading class Example]
[Loaded Example from __JVM_DefineClass__]
[Unloading class Example]
[Loaded Example from __JVM_DefineClass__]
[Unloading class Example]
[Loaded java.lang.Shutdown from D:\jre1.7\lib\rt.jar]
[Loaded java.lang.Shutdown$Lock from D:\jre1.7\lib\rt.jar]

示例3---打印类信息表

package chapter3;

public class Loop {
	public static void main(String[] args) throws InterruptedException {
		for (int i = 0; i < 100; i++) {
			System.out.println("hello world!");
			Thread.sleep(10000);
		}
	}
}

通过输入-XX:+PrintClassHistogram在程序执行时按ctrl+break(=ctrl+fn+B)输出类信息表:


3.系统参数查看

示例4--查看系统参数

代码沿用示例3。

虚拟机收到的命令行的显示参数:-XX:+PrintVMOptions

VM option '+TraceClassUnloading'

VM option '+TraceClassLoading'

VM option '+PrintClassHistogram'

VM option '+PrintVMOptions'

打印传递给虚拟机的显示参数和隐式参数:-XX:+PrintCommandLineFlags

-XX:InitialHeapSize=132582976 -XX:MaxHeapSize=2121327616 -XX:+PrintClassHistogram -XX:+PrintCommandLineFlags -XX:+TraceClassLoading -XX:+TraceClassUnloading -XX:+UseCompressedOops -XX:-UseLargePagesIndividualAllocation -XX:+UseParallelGC

查看系统的详细参数:-XX:+PrintFlagsFinal

2.学习堆的配置参数

1.最大堆和最小堆的设置

示例5---配置堆参数

package chapter3;

public class HeapAlloc {
	private final static int _1MB = 1024*1024;
	public static void main(String[] args) {
		
		System.out.print("maxMemory=");
		System.out.println(Runtime.getRuntime().maxMemory()/_1MB+"MB");
		System.out.print("free mem=");
		System.out.println(Runtime.getRuntime().freeMemory()/_1MB+"MB");
		System.out.print("total meme");
		System.out.println(Runtime.getRuntime().totalMemory()/_1MB+"MB");
		
		byte[] b = new byte[1*_1MB];
		System.out.println("分配1M空间给数组");
		
		System.out.print("maxMemory=");
		System.out.println(Runtime.getRuntime().maxMemory()/_1MB+"MB");
		System.out.print("free mem=");
		System.out.println(Runtime.getRuntime().freeMemory()/_1MB+"MB");
		System.out.print("total meme");
		System.out.println(Runtime.getRuntime().totalMemory()/_1MB+"MB");
		
		b = new byte[4*_1MB];
		System.out.println("分配4M空间给数组");
		
		System.out.print("maxMemory=");
		System.out.println(Runtime.getRuntime().maxMemory()/_1MB+"MB");
		System.out.print("free mem=");
		System.out.println(Runtime.getRuntime().freeMemory()/_1MB+"MB");
		System.out.print("total meme");
		System.out.println(Runtime.getRuntime().totalMemory()/_1MB+"MB");
	}
}

jvm参数设置为:

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

输出结果为:

-XX:InitialHeapSize=5242880 -XX:MaxHeapSize=20971520 -XX:+PrintCommandLineFlags -XX:+PrintGCDetails -XX:+UseCompressedOops -XX:-UseLargePagesIndividualAllocation -XX:+UseSerialGC 
maxMemory=19MB
free mem=4MB
total meme4MB
[GC[DefNew: 658K->127K(1536K), 0.0017391 secs] 658K->466K(4992K), 0.0017965 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
分配1M空间给数组
maxMemory=19MB
free mem=3MB
total meme4MB
[GC[DefNew: 1180K->0K(1536K), 0.0015228 secs][Tenured: 1490K->1490K(3456K), 0.0031215 secs] 1518K->1490K(4992K), [Perm : 2563K->2563K(21248K)], 0.0046967 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
分配4M空间给数组
maxMemory=19MB
free mem=3MB
total meme9MB
Heap
 def new generation   total 1664K, used 77K [0x00000000f9a00000, 0x00000000f9bc0000, 0x00000000fa0a0000)
  eden space 1536K,   5% used [0x00000000f9a00000, 0x00000000f9a135b0, 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, 0x00000000fa614a58, 0x00000000fa614c00, 0x00000000fa801000)
 compacting perm gen  total 21248K, used 2571K [0x00000000fae00000, 0x00000000fc2c0000, 0x0000000100000000)
   the space 21248K,  12% used [0x00000000fae00000, 0x00000000fb082c38, 0x00000000fb082e00, 0x00000000fc2c0000)
No shared spaces configured.

最大可用内存与最大内存少的原因:由于复制算法会将对象存活的对象复制到一块survivor中,所以最大可用内存为最大内存减去from区的大小。

2.新生代的设置

示例6---调整新生代的大小,观察它与GC次数的关系

package chapter3;

public class NewSizeDemo {
	public static void main(String[] args) {
		byte[] b = null;
		for (int i = 0; i < 10; i++) {
			b = new byte[1*1024*1024];
		}
	}
}

-Xmx20M -Xms20M-Xmn7M -XX:SurvivorRatio=2 -XX:+PrintGCDetails -XX:+UseSerialGC

[GC[DefNew: 2774K->1488K(5376K), 0.0022987 secs] 2774K->1488K(18688K), 0.0023433 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]

[GC[DefNew: 4641K->1024K(5376K), 0.0020457 secs] 4641K->1488K(18688K), 0.0020729 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]

[GC[DefNew: 4124K->1024K(5376K), 0.0009689 secs] 4589K->1488K(18688K), 0.0009919 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]

Heap

 def new generation   total 5376K, used 3162K [0x00000000f9a00000, 0x00000000fa100000, 0x00000000fa100000)

  eden space 3584K,  59% used [0x00000000f9a00000, 0x00000000f9c16a20, 0x00000000f9d80000)

  from space 1792K,  57% used [0x00000000f9f40000, 0x00000000fa040010, 0x00000000fa100000)

  to   space 1792K,   0% used [0x00000000f9d80000, 0x00000000f9d80000, 0x00000000f9f40000)

 tenured generation   total 13312K, used 464K [0x00000000fa100000, 0x00000000fae00000, 0x00000000fae00000)

   the space 13312K,   3% used [0x00000000fa100000, 0x00000000fa174258, 0x00000000fa174400, 0x00000000fae00000)

 compacting perm gen  total 21248K, used 2569K [0x00000000fae00000, 0x00000000fc2c0000, 0x0000000100000000)

   the space 21248K,  12% used [0x00000000fae00000, 0x00000000fb082580, 0x00000000fb082600, 0x00000000fc2c0000)

No shared spaces configured. 

-Xmx20M -Xms20M -Xmn7M -XX:SurvivorRatio=8 -XX:+PrintGCDetails -XX:+UseSerialGC

[GC[DefNew: 4860K->464K(6464K), 0.0021934 secs] 4860K->1488K(19776K), 0.0022451 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]

[GC[DefNew: 5708K->0K(6464K), 0.0021726 secs] 6732K->2512K(19776K), 0.0022013 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]

Heap

 def new generation   total 6464K, used 1081K [0x00000000f9a00000, 0x00000000fa100000, 0x00000000fa100000)

  eden space 5760K,  18% used [0x00000000f9a00000, 0x00000000f9b0e6d8, 0x00000000f9fa0000)

  from space 704K,   0% used [0x00000000f9fa0000, 0x00000000f9fa0088, 0x00000000fa050000)

  to   space 704K,   0% used [0x00000000fa050000, 0x00000000fa050000, 0x00000000fa100000)

 tenured generation   total 13312K, used 2512K [0x00000000fa100000, 0x00000000fae00000, 0x00000000fae00000)

   the space 13312K,  18% used [0x00000000fa100000, 0x00000000fa3741f0, 0x00000000fa374200, 0x00000000fae00000)

 compacting perm gen  total 21248K, used 2569K [0x00000000fae00000, 0x00000000fc2c0000, 0x0000000100000000)

   the space 21248K,  12% used [0x00000000fae00000, 0x00000000fb082580, 0x00000000fb082600, 0x00000000fc2c0000)

No shared spaces configured.

-Xmx20M -Xms20M -Xmn15M -XX:SurvivorRatio=8 -XX:+PrintGCDetails -XX:+UseSerialGC

Heap

 def new generation   total 13824K, used 11525K [0x00000000f9800000, 0x00000000fa700000, 0x00000000fa700000)

  eden space 12288K,  93% used [0x00000000f9800000, 0x00000000fa341728, 0x00000000fa400000)

  from space 1536K,   0% used [0x00000000fa400000, 0x00000000fa400000, 0x00000000fa580000)

  to   space 1536K,   0% used [0x00000000fa580000, 0x00000000fa580000, 0x00000000fa700000)

 tenured generation   total 5120K, used 0K [0x00000000fa700000, 0x00000000fac00000, 0x00000000fae00000)

   the space 5120K,   0% used [0x00000000fa700000, 0x00000000fa700000, 0x00000000fa700200, 0x00000000fac00000)

 compacting perm gen  total 21248K, used 2569K [0x00000000fae00000, 0x00000000fc2c0000, 0x0000000100000000)

   the space 21248K,  12% used [0x00000000fae00000, 0x00000000fb082580, 0x00000000fb082600, 0x00000000fc2c0000)

No shared spaces configured.

 

-Xmx20M -Xms20M -XX:NewRatio=2 -XX:+PrintGCDetails -XX:+UseSerialGC

[GC[DefNew: 4845K->464K(6144K), 0.0023531 secs] 4845K->1488K(19840K), 0.0024022 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]

[GC[DefNew: 5702K->0K(6144K), 0.0018932 secs] 6726K->2512K(19840K), 0.0019196 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]

Heap

 def new generation   total 6144K, used 1079K [0x00000000f9a00000, 0x00000000fa0a0000, 0x00000000fa0a0000)

  eden space 5504K,  19% used [0x00000000f9a00000, 0x00000000f9b0dca0, 0x00000000f9f60000)

  from space 640K,   0% used [0x00000000f9f60000, 0x00000000f9f60088, 0x00000000fa000000)

  to   space 640K,   0% used [0x00000000fa000000, 0x00000000fa000000, 0x00000000fa0a0000)

 tenured generation   total 13696K, used 2512K [0x00000000fa0a0000, 0x00000000fae00000, 0x00000000fae00000)

   the space 13696K,  18% used [0x00000000fa0a0000, 0x00000000fa3141f0, 0x00000000fa314200, 0x00000000fae00000)

 compacting perm gen  total 21248K, used 2569K [0x00000000fae00000, 0x00000000fc2c0000, 0x0000000100000000)

   the space 21248K,  12% used [0x00000000fae00000, 0x00000000fb082580, 0x00000000fb082600, 0x00000000fc2c0000)

No shared spaces configured.

 

由此可以得出:新生代内存越大,GC次数越少;survivor适当减小,gc次数也会减少;所以应尽可能地将对象预留在新生代,减少老年代GC的次数。同时保证老年代有足够的空间进行担保。

3.堆溢出处理

示例7--堆溢出信息处理

package chapter3;

import java.util.Vector;

public class DumpOOM {
	public static void main(String[] args) {
		Vector<byte[]> v = new Vector<byte[]>();
		for(int i=0;i<25;i++){
			v.add(new byte[1*1024*1024]);
		}
	}
}

jvm参数:

-Xmx20M -Xms5M"-XX:OnOutOfMemoryError=D:/jdk1.7/bin/printstack.bat %p"-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=D:/program2015/jvm/src/a.dump

创建脚本工具printstack,是程序在堆栈溢出时尽心打印


printstack.bat:


输出结果:

java.lang.OutOfMemoryError: Java heap space
Dumping heap to D:/program2015/jvm/src/a.dump ...
Unable to create D:/program2015/jvm/src/a.dump: File exists
#
# java.lang.OutOfMemoryError: Java heap space
# -XX:OnOutOfMemoryError="D:/jdk1.7/bin/printstack.bat %p"
#   Executing "D:/jdk1.7/bin/printstack.bat 7288"...
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
	at chapter3.DumpOOM.main(DumpOOM.java:9)

使用mat工具查看:



3.非堆内存参数设置

方法区设置、栈设置参考之前文章:https://blog.csdn.net/yinweicheng/article/details/80624259https://blog.csdn.net/yinweicheng/article/details/80607402

直接内存配置

示例8--直接内存与堆内存的访问速度

代码片1:访问读写速度

package chapter3;

import java.nio.ByteBuffer;

public class AccessDirectBuffer {
	public void directAccess(){
		long starttime = System.currentTimeMillis();
		ByteBuffer b = ByteBuffer.allocateDirect(500);
		for (int i = 0; i < 100000; i++) {
			for (int j = 0; j < 99	; j++) {
				b.putInt(j);
			}
			b.flip();
			for (int j = 0; j < 99	; j++) {
				b.getInt();
			}
			b.clear();
		}
		long endtime = System.currentTimeMillis();
		System.out.println("testDirectWrite:"+(endtime-starttime));
	}
	public void bufferAccess(){
		long starttime = System.currentTimeMillis();
		ByteBuffer b = ByteBuffer.allocate(500);
		for (int i = 0; i < 100000; i++) {
			for (int j = 0; j < 99	; j++) {
				b.putInt(j);
			}
			b.flip();
			for (int j = 0; j < 99	; j++) {
				b.getInt();
			}
			b.clear();
		}
		long endtime = System.currentTimeMillis();
		System.out.println("testBufferWrite:"+(endtime-starttime));
	}
	public static void main(String[] args) {
		AccessDirectBuffer alloc = new AccessDirectBuffer();
		alloc.bufferAccess();
		alloc.directAccess();
		alloc.bufferAccess();
		alloc.directAccess();
	}
}

输出结果:


使用-server模式后:


代码片2:内存空间申请

package chapter3;

import java.nio.ByteBuffer;

public class AccessDirecBuffer1 {
	public void directAccess(){
		long starttime = System.currentTimeMillis();
		for (int i = 0; i < 200000; i++) {
			ByteBuffer b = ByteBuffer.allocateDirect(1000);
		}
		long endtime = System.currentTimeMillis();
		System.out.println("testDirectWrite:"+(endtime-starttime));
	}
	public void bufferAccess(){
		long starttime = System.currentTimeMillis();
		for (int i = 0; i < 200000; i++) {
			ByteBuffer b = ByteBuffer.allocate(1000);
		}
		long endtime = System.currentTimeMillis();
		System.out.println("testBufferWrite:"+(endtime-starttime));
	}
	public static void main(String[] args) {
		AccessDirecBuffer1 alloc = new AccessDirecBuffer1();
		alloc.bufferAccess();
		alloc.directAccess();
		alloc.bufferAccess();
		alloc.directAccess();
	}
}

输出结果:


可见,直接内存在进行访问读写操作时速度较快,而在申请内存空间时没有任何优势,所以直接内存适合申请次数少、访问频繁的场合。不适用于内存空间频繁申请的场合。

4.虚拟机的工作模式

server倾向于解释执行,会尝试收集更多的系统信息。



猜你喜欢

转载自blog.csdn.net/yinweicheng/article/details/80650648