arctic_fox

贵有恒何必三更眠五更起 最无益只怕一日曝十日寒

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

 

JVM 参数调优:

   

堆空间主要组成部分:

   

1:新生代(new generation),新生代又划分为3部分:

1 eden

2 From Survivor(s0区域)

3 To Survivor(s1区域)

其中s0和s1区域大小相等

2:老年代(tenured generation)

   

new出来的对象都会存放在堆内存中

   

新生代和老年代的存在主要用于垃圾回收机制,其中主要针对的是新生代,因为对象首先分配在eden区,在新生代回收后,如果对象还存活,则进入s0或s1区,之后每经过一次新生代回收,如果对象存活则它的年龄就加1,对象达到一定的年龄后,则进入老年代。

   

JVM调优方案:

相关优化参数

-Xms 

堆初始值

  

-Xmx 

堆最大可用值

  

-Xmn

新生代最大可用值

一般为堆大小的1/3或者1/4

-XX:SurvivorRatio

设置新生代中eden空间和from/to空间的比例

-XX:SurvivorRatio=eden/from=eden/to

-XX:NewRatio

设置老年代和新生代比例

-XX:NewRatio=老年代/新生代

   

   

思路:

   

在JVM启动参数中,可以设置跟内存、垃圾回收相关的一些参数设置,默认情况不做任何设置JVM会工作的很好,但对一些配置很好的Server和具体的应用必须仔细调优才能获得最佳性能。通过设置我们希望达到一些目标:

1、GC的时间足够的小

2、GC的次数足够的少

3、发生Full GC(新生代和老年代)的周期足够的长

前两个目前是相悖的,要想GC时间小必须要一个更小的堆,要保证GC次数足够少,必须保证一个更大的堆,我们只能取其平衡。

(1)针对JVM堆的设置,一般可以通过-Xms -Xmx限定其最小、最大值,为了防止垃圾收集器在最小、最大之间收缩堆而产生额外的时间,我们通常把最大、最小设置为相同的值

(2)年轻代和年老代将根据默认的比例(1:2)分配堆内存,可以通过调节二者的比例为1:3或者1:4,当然也可以设置新生代的大小,原则上为堆空间的1/3或者1/4

   

// 设置老年代和新生代比例为3:1

-Xms20m -Xmx20m -XX:SurvivorRatio=8 -XX:NewRatio=3 -XX:+PrintGCDetails -XX:+UseSerialGC

package com.linxi.jia;

   

/**

* Created by 156 on 2019/2/13.

*/

public class JvmDemo02 {

   

// 设置新生代和老年代优化参数

public static void main(String[] args) {

//-Xms20m -Xmx20m -XX:SurvivorRatio=8 -XX:NewRatio=3 -XX:+PrintGCDetails -XX:+UseSerialGC

byte [] b = null;

for (int i = 0; i < 2; i++) {

b =new byte[1*1024*1024];

}

   

}

}

   

// 设置新生代大小为堆的1/4

-Xms20m -Xmx20m -Xmn5m -XX:SurvivorRatio=8 -XX:+PrintGCDetails -XX:+UseSerialGC

   

上面两种方式任选一种即可。

   

(3)年轻代和年老代设置多大才算合理?这个我问题毫无疑问是没有答案的,否则也就不会有调优。我们观察一下二者大

小变化有哪些影响更大的年轻代必然导致更小的年老代,大的年轻代会延长普通GC的周期,但会增加每次GC的时间;小的年老代会导致更频繁的Full GC更小的年轻代必然导致更大年老代,小的年轻代会导致普通GC很频繁,但每次的GC时间会更短;大的年老代会减少Full GC的频率如何选择应该依赖应用程序对象生命周期的分布情况:如果应用存在大量的临时对象,应该选择更大的年轻代;如果存在相对较多的持久对象,年老代应该适当增大。但很多应用都没有这样明显的特性,在抉择时应该根据以下点:(A)本着Full GC尽量少的原则,让年老代尽量缓存常用对象,JVM的默认比例1:2也是这个道理(B)通过观察应用一段时间,看其他在峰值时年老代会占多少内存,在不影响Full GC的前提下,根据实际情况加大年轻 代,比如可以把比例控制在1:1。但应该给年老代至少预留1/3的增长空间

   

   

堆内存溢出

   

栈内存溢出

   

错误原因: java.lang.StackOverflowError 栈内存溢出

栈溢出 产生于递归调用,循环遍历是不会的,但是循环方法里面产生递归调用, 也会发生栈溢出。

解决办法:设置线程最大调用深度

-Xss5m 设置最大调用深度

   

Tomcat内存溢出在catalina.sh 修改JVM堆内存大小

JAVA_OPTS="-server -Xms800m -Xmx800m -XX:PermSize=256m -XX:MaxPermSize=512m -XX:MaxNewSize=512m"

posted on 2019-08-07 17:04  月染霜华  阅读(196)  评论(0编辑  收藏  举报