JVM参数调优

JVM参数配置

JVM提供了诸多的参数进行JVM各个方面内存大小的设置,为Java应用进行优化提供了诸多的工具,本文将会详细分析各个参数的功能与使用。

常见参数配置

-XX:+PrintGC      每次触发GC的时候打印相关日志

-XX:+UseSerialGC      串行回收

-XX:+PrintGCDetails  更详细的GC日志

-Xms               堆初始值

-Xmx               堆最大可用值

-Xmn               新生代堆最大可用值

-XX:SurvivorRatio  用来设置新生代中Eden空间和from/to空间的比例.

-XX:NewRatio       配置新生代与老年代占比 1:2

含以-XX:SurvivorRatio=Eden/from=den/to

总结:在实际工作中,我们可以直接将初始的堆大小与最大堆大小相等,

这样的好处是可以减少程序运行时垃圾回收次数,从而提高效率。

-XX:SurvivorRatio     用来设置新生代中Eden空间和from/to空间的比例.

 

总结补充:

  • 初始堆内存与电脑内存有关,默认4G 。 
  • 对于新生代最大可用值,满了发生Minor GC
  • 触发Full GC ,新生代、老年代都会一起回收了

 

堆的初始值和最大值一定要相等,不相等的情况下,垃圾不停的回收,不停的申请,不停的回收 ..... 

  1.  垃圾回收时候 其他线程要停止,停顿一下( 如果不暂停,再次期间产生的新的垃圾不能回收。)。如果堆内存和最大不同,则不停回收。那么程序断断续续的进行,非常不好。大家要注意!    
  2.  新生代小于老年代 。新生代回收的频率高,老年代低。 让新生代去频繁收集 所以调小一些     新生代:老年代=1:2  新生代占比越小越频繁 老年代打不频繁

 

实战一、堆内存大小配置

package jvmTest;

//打印堆的基本内存信息
public class Test02 {
  public static void main(String[] args) {
        System.out.print("最大内存");
        System.out.println(Runtime.getRuntime().maxMemory() / 1024.0 / 1024 + "M");
        System.out.print("可用内存");
        System.out.println(Runtime.getRuntime().freeMemory() / 1024.0 / 1024 + "M");
        System.out.print("已经使用内存");
        System.out.println(Runtime.getRuntime().totalMemory() / 1024.0 / 1024 + "M");
}
        
}

这是默认的堆存的状态

 进行设置: -Xmx20m -Xms5m     初始5m 最大20m

  

运行结果:

已使用内存 根据初始值申请来的  !

来4M的内存看看:

package jvmTest;

//打印堆的基本内存信息
public class Test02 {
  public static void main(String[] args) {
        byte[] b = new byte[4 * 1024 * 1024];  //4M
        System.out.print("最大内存");
        System.out.println(Runtime.getRuntime().maxMemory() / 1024.0 / 1024 + "M");
        System.out.print("可用内存");
        System.out.println(Runtime.getRuntime().freeMemory() / 1024.0 / 1024 + "M");
        System.out.print("已经使用内存");
        System.out.println(Runtime.getRuntime().totalMemory() / 1024.0 / 1024 + "M");
}
        
}

运行结果:

使用内存 > 9M

但是不能申请25M给它哦,会堆溢出的~大家可以试试

 

 

 

设置新生代比例参数

使用示例: -Xms20m   -Xmx20m  -Xmn1m  -XX:SurvivorRatio=2  -XX:+PrintGCDetails -XX:+UseSerialGC

说明:堆内存初始化值20m,堆内存最大值20m,新生代最大值可用1m,Eden空间和from/to空间的比例为2/1     (2:1:1)

 Eden 默认 比S0、S1要大。因为S0、S1要复制的不要太大了

package jvmTest;

//打印堆的基本内存信息
public class Test02 {
  public static void main(String[] args) {
      System.out.println("ssssss");
      byte[] b = null;
      for (int i = 0; i < 10; i++) {
      b = new byte[1 * 1024 * 1024];
      }

 }
  }    

结果:

出现框框内的 说明内存不够 进行垃圾回收了

下面的分配:

配置新生代的

 Eden空间和from/to空间的比例为2/1   2:1:1   结果展示完美

 

下面这么配置一下看看:

 -XX:+PrintGCDetails -XX:+UseSerialGC

 

结果没有回收哦

最大始值设置20M时候会有 GC回收日志

  因为之前这段代码运行时候 需要的内存是 10M i=10嘛  但是这时候新生代最大可用值是1M   这时候空间不够 为了够用 不停的回收   内存不够了就会不停的回收 

 

 

设置新生代与老年代比例参数

使用示例: -Xms20m -Xmx20m -XX:SurvivorRatio=2 -XX:+PrintGCDetails -XX:+UseSerialGC -XX:NewRatio=2

说明:堆内存初始化值20m,堆内存最大值20m,新生代最大值可用1m,eden空间和from/to空间的比例为2/1

新生代和老年代的占比为1/2

哇,竟然回收了三次!

 

新生代与老年的的占比是 1:2 看到eden+from+to : 1369 大致是哦

当然我们可以看下默认占比

大致为:13696:6784=1:2 

 

 

补充Tomca调优经验:

经验结论:

  1. 垃圾回收次数和设置最大堆内存大小无关,只和初始内存有关系。初始内存会影响吞吐量。
  2. 堆的初始值和最大堆内存一致,并且初始堆越大就会高。
  3. 初始堆值和最大堆内存内存越大,吞吐量就越高。
  4. 最好使用并行收集器,因为并行收集器速度比串行吞吐量高,速度快。
  5. 设置堆内存新生代的比例和老年代的比例最好为1:2或者1:3。
  6. 减少GC对老年代的回收。
posted @ 2018-10-29 23:45  toov5  阅读(398)  评论(0编辑  收藏  举报