Java性能优化-练习

来源:互联网 发布:手机对讲机软件 编辑:程序博客网 时间:2024/05/16 19:37

参考书籍:  实战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左右。



 





原创粉丝点击