Java性能优化-练习

参考书籍:  实战JAVA虚拟机  JVM故障诊断与性能优化

参考unixboy的博客,网址:https://unixboy.iteye.com/blog/174173/

 

 

JVM中最大堆大小有三方面的限制,操作系统、系统可用虚拟内存限制、系统可用物理内存限制。32位系统,一般限制在1.5G-2G,64位系统无限制。

典型设置:

一、java  -Xmx3550m  -Xms3550m -Xmn2g -Xss128k

-Xmx3550m:设置JVM最大可用内存为3550m

-Xms3550m:设置JVM初始内存为3550m,此值可与-Xmx相同,以避免每次垃圾回收完成后JVM重新分配内存。

-Xmn2g:设置nian年轻代大小为2G。整个JVM内存大小=年轻代大小+年老代大小+持久代大小。持久代大小一般固定为64M。

Sun官方推荐配置为整个堆的3/8。

-Xss128k: 设置每个线程的最大栈空间,这个参数直接决定了函数的调用深度。JDK5.0以后每个线程堆栈为1M,以前每个线程堆栈大小为256k。相同物理内存下,减少这个值能生成更多的线程,但是操作系统对一个进程内的线程还是有限制的,不能无限生成,经验值在3000-5000左右。

 

二、java -Xmx3550m -Xms3550m -Xss128k -XX:NewRatio=4 -XX:SurvivorRatio=4 -XX:MaxPermSize=16m -XX:MaxTenuringThreshold=0

-XX:NewRatio=4 :设置年轻代(Eden区和SurvivorRatio)与年老代的比值(除去持久代)。故年轻代:年老代=1:4,年轻代占整个堆栈的1/5。

-XX:SurvivorRatio=4 :设置年轻代中Survivor与Eden的比值,大小为4,即Survivor与Eden的比值=2:4,即一个survivor占整个           年轻代的1/6,。

-XX:MaxPermSize=16m 设置持久代大小为16m。

-XX:MaxTenuringThreshold=0:设置垃圾最大年龄,如果设置为0的话,则年轻代对象不经过Survivor区,直接进入年老代。对于年老代比较多的应用,可以提高效率。如果将此值设置为一个较大值,则年轻代对象会在Survivor区进行多次复制,这样可以增加对象再年轻代的存活时间,增加在年轻代即被回收的概论。

 

Ratio:比例,系数

survivor:sheg生还者,幸存者

 

三、JVM给了三种选择:串行收集器、并行收集器、并发收集器。

吞吐量优先的并行收集器,适用于科学技术和后台处理等。

典型配置:

java   -Xmx3100m  -Xms3100m  -Xmn2g  -Xss128k -XX:+UseParallelGC -XX:ParallelGCThreads=20

-XX:+UseParallelGC:选择垃圾收集器为并行收集器,此配置对年轻代有效,即年轻代使用并行收集,年老代仍然是串行收集。

-XX:ParallelGCThreads=20 配置并行收集器的线程数,此值最好配置与处理器数目相等。

 

java -Xmx3550m -Xms3550m -Xmn2g -Xss128k -XX:+UseParallelGC -XX:ParallelGCThreads=20 -XX:+UseParallelOldGC

-XX:+UseParallelOldGC 配置年老代使用并行收集,JDK6.0支持对年老代并行收集。

 

  • java -Xmx3550m -Xms3550m -Xmn2g -Xss128k -XX:+UseParallelGC  -XX:MaxGCPauseMillis=100
    -XX:MaxGCPauseMillis=100:设置每次年轻代垃圾回收的最长时间,如果无法满足此时间,JVM会自动调整年轻代大小,以满足此值。
  • java -Xmx3550m -Xms3550m -Xmn2g -Xss128k -XX:+UseParallelGC  -XX:MaxGCPauseMillis=100 -XX:+UseAdaptiveSizePolicy
    -XX:+UseAdaptiveSizePolicy
    :设置此选项后,并行收集器会自动选择年轻代区大小和相应的Survivor区比例,以达到目标系统规定的最低相应时间或者收集频率等,此值建议使用并行收集器时,一直打开。

响应时间优先的并发收集器
如上文所述,并发收集器主要是保证系统的响应时间,减少垃圾收集时的停顿时间。适用于应用服务器、电信领域等。
典型配置

  • java -Xmx3550m -Xms3550m -Xmn2g -Xss128k -XX:ParallelGCThreads=20 -XX:+UseConcMarkSweepGC -XX:+UseParNewGC
    -XX:+UseConcMarkSweepGC:设置年老代为并发收集。测试中配置这个以后,-XX:NewRatio=4的配置失效了,原因不明。所以,此时年轻代大小最好用-Xmn设置。
    -XX:+UseParNewGC:设置年轻代为并行收集。可与CMS收集同时使用。JDK5.0以上,JVM会根据系统配置自行设置,所以无需再设置此值。
  • java -Xmx3550m -Xms3550m -Xmn2g -Xss128k -XX:+UseConcMarkSweepGC -XX:CMSFullGCsBeforeCompaction=5 -XX:+UseCMSCompactAtFullCollection
    -XX:CMSFullGCsBeforeCompaction:由于并发收集器不对内存空间进行压缩、整理,所以运行一段时间以后会产生“碎片”,使得运行效率降低。此值设置运行多少次GC以后对内存空间进行压缩、整理。
    -XX:+UseCMSCompactAtFullCollection:打开对年老代的压缩。可能会影响性能,但是可以消除碎片

 

mark:记号,concurrent同时发生的

  1. ParaellGC是Stop the application,之后多个线程去收集可回收的内存,之后执行回收操作,关键点是:确认哪些内存可以回收、之后再回收,俩个操作都在Stop application后才执行的。
  2. CMS也是Stop the application,但是:初始标记,确认哪些内存可以被回收是与业务线程同时执行的;之后是重新标记阶段,这个阶段会Stop the application;之后是回收阶段,这个阶段是和业务线程同时执行着的。

 

 

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左右。

 

 

 

 

 

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值