您的位置:首页 > 运维架构 > Tomcat

tomcat jvm内存调优,OutOfMemoryError

2016-04-23 21:01 471 查看
服务器迁移,新机器内存比以前的小,发现应用起不来。

报错:java.lang.OutOfMemoryError: PermGen space。看起来是永久代内存溢出了。

修改TOMCAT_HOME/bin/catalina.sh ,在第一行添加:

JAVA_OPTS="-server -Xms256m -Xmx1024m -XX:PermSize=128M -XX:MaxPermSize=256m" 

改大永久代内存空间大小,重启应用即可。

一、了解jvm内存的构成

JVM区域总体分两类,heap区和非heap区。

heap区又分:Eden Space(伊甸园)、Survivor Space(幸存者区)、Tenured Gen(老年代-养老区)。

非heap区又分:Code Cache(代码缓存区)、Perm Gen(永久代)、Jvm Stack(java虚拟机栈)、Local Method Statck(本地方法栈)。

非heap区域中Perm Gen中放着类、方法的定义,jvm Stack区域放着方法参数、局域变量等的引用,方法执行顺序按照栈的先入后出方式。

HotSpot虚拟机GC算法采用分代收集算法:

1、一个人(对象)出来(new 出来)后会在Eden Space(伊甸园)无忧无虑的生活,直到GC到来打破了他们平静的生活。GC会逐一问清楚每个对象的情况,有没有钱(此对象的引用)啊,因为GC想赚钱呀,有钱的才可以敲诈嘛。然后富人就会进入Survivor Space(幸存者区A),穷人的就直接kill掉。

2、并不是进入Survivor Space(幸存者区)后就保证人身是安全的,但至少可以活段时间。GC会定期(可以自定义)会对这些人进行敲诈,有钱就搬到幸存者区B(有两个幸存者区,每次切换腾出一个空的,供下次使用)。每次清理都给留下来的对象计数加1,存活次数到达阀值,就让其进入了Genured Gen(养老区)。

3、进入到养老区的人基本就可以保证人身安全啦,但是养老区存储到达阀值,GC还是会来清理没用的对象。

二、分析jvm

1、查出jvm进程id

[root@VM_223_111_centos ~]# ps -ef|grep java

root      4927     1  1 17:57 ?        00:01:22 /usr/local/jdk1.7.0_79/bin/java  -Dcatalina.home=/usr/local/tomcat7 -Djava.io.tmpdir=/usr/local/tomcat7/temp org.apache.catalina.startup.Bootstrap start

root     16522 12274  0 19:58 pts/0    00:00:00 grep tomcat

2、jmap分析jvm

jmap -heap 4927



perm gen太小了,这就是报错的原因,所以我要适当调大。

3、利用tomcat管理jvm亦可

在conf/tomcat-users.xml中加入配置用户jvm

<tomcat-users>

<role rolename="manager-gui"/>

<user username="jvm" password="jvmstatus" roles="manager-gui"/>

</tomcat-users>

以下是Tomcat Manager 4种角色的大致介绍(下面URL中的*为通配符):

manager-gui

允许访问html接口(即URL路径为/manager/html/*)

manager-script

允许访问纯文本接口(即URL路径为/manager/text/*)

manager-jmx

允许访问JMX代理接口(即URL路径为/manager/jmxproxy/*)

manager-status

允许访问Tomcat只读状态页面(即URL路径为/manager/status/*)

登录管理页,即可查看内存情况



三、jvm参数说明: 

-server:一定要作为第一个参数,在多个CPU时性能佳 

-Xms:java Heap初始大小。 默认是物理内存的1/64。

-Xmx:java heap最大值。建议均设为物理内存的一半。不可超过物理内存。

-XX:PermSize:设定内存的永久保存区初始大小,缺省值为64M。

-XX:MaxPermSize:设定内存的永久保存区最大 大小,缺省值为64M。

-XX:SurvivorRatio=2  :生还者池的大小,默认是2,如果垃圾回收变成了瓶颈,您可以尝试定制生成池设置 

-XX:NewSize: 新生成的池的初始大小。 缺省值为2M。

-XX:MaxNewSize: 新生成的池的最大大小。   缺省值为32M。

如果 JVM 的堆大小大于 1GB,则应该使用值:-XX:newSize=640m -XX:MaxNewSize=640m -XX:SurvivorRatio=16,或者将堆的总大小的 50% 到 60% 分配给新生成的池。调大新对象区,减少Full GC次数。

参考:

1、JVM内存区域划分    http://my.oschina.net/u/175660/blog/351702
2、Tomcat内存设置详解 http://elf8848.iteye.com/blog/378805
3、JVM性能调优        http://uule.iteye.com/blog/2114697
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: