Activemq报错java.lang.OutOfMemoryError: PermGen space解决方法

最近公司一台activemq经常出现卡死的现象,页面响应缓慢,基本无法操作,只能重启activemq解决。

之前好好的,最近怎么老是出现这种问题?难道是消息量增加导致的。

后来在故障发生的时间段看了下activemq的日志,发现有以下错误:java.lang.OutOfMemoryError: PermGen space

网上查到都有类似的情况,但不是activemq,都是tomcat、jboss类似,不过都是java的应用,解决方法应该类似。主要就是因为Perm内存不足,默认是64M。

 

编辑activemq执行文件 /opt/activemq/bin/activemq,默认的配置是:
ACTIVEMQ_OPTS_MEMORY="-Xms1G -Xmx1G"

改为:
ACTIVEMQ_OPTS_MEMORY="-Xms1G -Xmx1G  -Xmn256M -XX:PermSize=512M -XX:MaxPermSize=512M"

解释下以上的参数(网上摘抄):

Xms/Xmx:定义NEW+OLD段的总尺寸,ms为JVM启动时NEW+OLD的内存大小;mx为最大可占用的NEW+OLD内存大小。在用户生产环境上一般将这两个值设为相同,以减少运行期间系统在内存申请上所花的开销;
NewSize/MaxNewSize:定义单独NEW段的尺寸,NewSize为JVM启动时NEW的内存大小;MaxNewSize为最大可占用的NEW的内存大小。在用户生产环境上一般将这两个值设为相同,以减少运行期间系统在内存申请上所花的开销;

Xms/Xmx和NewSize/MaxNewSize定义好后,OLD区间也自然定义完毕了,即OLD区初始大小=(Xms-NewSize),OLD区最大可占用大小=(Xmx-MaxNewSize);
PermSize/MaxPermSize:定义Perm段的尺寸,PermSize为JVM启动时Perm的内存大小;MaxPermSize为最大可占用的Perm内存大小。在用户生产环境上一般将这两个值设为相同,以减少运行期间系统在内存申请上所花的开销。

-Xmx:设置JVM最大可用内存。
-Xms:设置JVM促使内存为。此值可以设置与-Xmx相同,以避免每次垃圾回收完成后JVM重新分配内存。
-Xmn:设置年轻代大小。整个JVM内存大小=年轻代大小 + 年老代大小 + 持久代大小。持久代一般固定大小为64m,所以增大年轻代后,将会减小年老代大小。此值对系统性能影响较大,Sun官方推荐配置为整个堆的3/8。
-Xss: 设置每个线程的堆栈大小。JDK5.0以后每个线程堆栈大小为1M,以前每个线程堆栈大小为256K。更具应用的线程所需内存大小进行调整。在相同物理内 存下,减小这个值能生成更多的线程。但是操作系统对一个进程内的线程数还是有限制的,不能无限生成,经验值在3000~5000左右。

自己总结如下:

-Xmn相当于NewSize/MaxNewSize定义同样的值,只要设定了-Xmn如256M,就相当于设定了NewSize和MaxNewSize相等并且值为256M

Xms  Xmx 、 NewSize MaxNewSize和PermSize、MaxPermSize若内存足够,在实际应用中都应该设置相等,以减少运行期间系统在内存申请上所花的开销。

推荐设置的相关比例(前提是你的服务器是专门给MQ用的):
Xms  Xmx 设置为物理内存的80%,Xmn为Xmx的四分之一。

PermSize、MaxPermSize据网上所说设置为256M就足够了,反正内存多512M也没关系。

Xms  Xmx 、 NewSize MaxNewSize 是堆内存,给JAVA应用程序用

PermSize、MaxPermSize是非堆内存,给JAVA自己用