Java性能优化-练习
参考书籍: 实战JAVA虚拟机 JVM故障诊断与性能优化
1 获取运行环境的Xmx
System.out.println("-Xmx"+Runtime.getRuntime().maxMemory()/1000/1000+"M");
-Xmx1888M
2 堆,方法区和Java栈存放
public class SimpleHeap {
private int id;
public SimpleHeap(int id){
this.id=id;
}
public void show(){
System.out.println("My ID is "+id);
}
public static void main(String[] args) {
SimpleHeap s1=new SimpleHeap(1);
SimpleHeap s2=new SimpleHeap(2);
s1.show();
s2.show();
}
}
3 Java堆分为新生代和老年代
新生代分eden区,s0区(from区)、s1区(to区)。老年代为tenured区。
-Xmx20m -Xms5m -XX:+PrintCommandLineFlags -XX:PrintGCDetails -XX:+UseSerialGC
具体分配如下:实际输出为:maxMemory=20316160 bytes
当前最大内存由:-XX:MaxHeapSize=20971520 即为:20*1024*1024=20971520
实际可用内存会浪费大小等于from/to的空间,-Xmx的值减去from的大小,from大小为131072,此时
20971520-131072=20840488,仍然有偏差,因需进一步做了对齐操作。
4 Java栈
Java是线程私有的内存空间,和线程有关。Java堆和程序有关。
-Xss指定线程的最大栈空间,决定了函数调用的最大深度。
如:
public class TestStackDeep {
private static int count=0;
public static void recursion(){
count++;
recursion();
}
public static void main(String[] args) {
// TODO Auto-generated method stub
try{
recursion();
}catch(Throwable e){
System.out.println("deep of calling ="+count);
e.printStackTrace();
}
}
}
修改-Xss的值,可以增加循环的次数。同时如果减少recursion方法中的局部变量,可以增加循环的次数。
5 方法区
在JDK1.6和JDK1.7中,方法区可理解为永久区(Perm),永久区可以使用参数-XX:PermSize和-XX:MaxPermSize指定。默认-XX:MaxPermSize为64M。
-XX:+PrintGCDetails -XX:PermSize=5M -XX:MaxPermSize=5m.
在JDK1.8中,永久区被彻底移除,而是元数据区,大小可以使用-XX:MaxMetaspaceSize指定,可以加载更多的类,这是一块堆外的直接内存。与永久区不同,如果不指定大小,默认会耗尽所有的可用系统内存。
第三章:
1 打印GC的日志
-XX:+PrintGC,只要有GC就会打印日志。
-XX:+PrintGCDetails,会打印更加详细的GC日志。
-XX:+PrintHeapAtGC 会在每次GC前后分别打印堆的信息。
-XX:+PrintGCTimeStamps 每次GC时,额外输出GC发生的时间。
-XX:+PrintGCApplicationConcurrentTime可以打印程序的执行时间
-XX:+PrintGCApplicationStoppedTime应用程序由于GC 而产生的停顿时间。
-XX:+TraceClassLoading 跟踪类的加载
-XX:+TraceClassUnloading 跟踪类的卸载
-XX:+PrintVMOptions
-Xmn可以设置新生代的大小,新生代的大小一般设置为整个堆空间的1/3到1/4左右。
-XX:SurvivorRatio用来设置新生代中eden空间和from/to空间的比例关系。
-XX:SurvivorRatio=eden/from=eden/to
(50页)
具体实例:
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];
}
}
}
1 -Xmx20m -Xms20m -Xmn1m -XX:SurvivorRatio=2 -XX:+PrintGCDetails
eden与from的比值为2:1,故eden区为512KB,其他from和to分别为256KB
2 下面的发生了3次新生代的GC
[GC [PSYoungGen: 2702K->1656K(5376K)] 2702K->1656K(18688K), 0.0074134 secs] [Times: user=0.00 sys=0.00, real=0.01 secs]
[GC [PSYoungGen: 4771K->1640K(5376K)] 4771K->1640K(18688K), 0.0005884 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[GC [PSYoungGen: 4740K->1576K(5376K)] 4740K->1576K(18688K), 0.0004804 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
Heap
PSYoungGen total 5376K, used 3858K [0x00000000ff900000, 0x0000000100000000, 0x0000000100000000)
eden space 3584K, 63% used [0x00000000ff900000,0x00000000ffb3a8d0,0x00000000ffc80000)
from space 1792K, 87% used [0x00000000ffc80000,0x00000000ffe0a030,0x00000000ffe40000)
to space 1792K, 0% used [0x00000000ffe40000,0x00000000ffe40000,0x0000000100000000)
ParOldGen total 13312K, used 0K [0x00000000fec00000, 0x00000000ff900000, 0x00000000ff900000)
object space 13312K, 0% used [0x00000000fec00000,0x00000000fec00000,0x00000000ff900000)
PSPermGen total 21248K, used 2561K [0x00000000f9a00000, 0x00000000faec0000, 0x00000000fec00000)
object space 21248K, 12% used [0x00000000f9a00000,0x00000000f9c80438,0x00000000faec0000)
3 -Xmx20m -Xms20m -XX:NewRatio=2 -XX:+PrintGCDetails
-XX:NewRatio=老年代/新生代,此新生代即为20/3=6m左右,老年代13m左右。