跟踪垃圾回收和类加载信息
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/80624259、https://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倾向于解释执行,会尝试收集更多的系统信息。