Tomcat非堆内存溢出

如下内容来源于网络,参考内容连接:html

https://www.cnblogs.com/wulaijun/p/5490699.htmljava

http://blog.51cto.com/lizhenliang/1763866算法

项目测试环境,开启Tomcat,运行一段时间以后,出现内存溢出状况,报错以下:网络

OutOfMemoryError: PermGen space   非堆溢出(永久保存区域溢出)测试

首先了解Tomcat的内存机制:spa

一.Tomcat运行环境介绍操作系统

1.Tomcat自己没法直接在计算机上运行,须要依赖硬件基础上的操做系统和java虚拟机;server

2.java程序启动时JVM会分配一个初始内存和最大内存给这个应用;htm

3.当应用程序用到最大内存时,就会触发JVM作垃圾回收(GC)动做,释放被占用的内存;对象

4.所以想要调整java程序启动时的初始内存和最大内存,须要向JVM申请;

5.若是初始内存大小设置太小,且此时初始化的应用对象过多,虚拟机就必须重复的加载内存来知足使用;

6.基于以上缘由,最好把初始内存(Xms)和最大内存(Xmx)设置成同样;

7.JVM上全部的对象都在“堆区(heap)”上分配内存(也有在栈上分配内存的)

8.堆的大小是能够动态扩展的,但“”堆“的大小受限于系统使用的物理内存,当应用程序须要的内存超出“堆”的最大值时,JVM虚拟机就会抛出内存溢出异常,而且致使应用程序崩溃;

9.基于以上缘由,建议“堆”的大小设置成物理内存的80%;

二.JVM相关基础概念

1)JVM内存划分分为年轻代(young generation)、老年代(old generation)、永久代(permanent generation)

2)年轻代又分为Eden和survivor区,survivor区由fromspace和tospace组成,Eden区占大容量,survivor区两个区占小容量,默认比例为8:2

3)堆内存(heap)=年轻代+老年代。非堆内存=永久代

4)堆内存用处:存放的是对象,垃圾收集器就是收集这些对象,而后根据算法GC算法回收。

5)非堆内存用处:JVM自己使用,存放一些类、方法、常量、属性等。

6)年轻代:新生成的对象首先放到年轻代的Eden区中,当Eden满时,通过GC后,还存活的对象被复制到survivor区的fromspace中,若是survivor区满时,会再被复制到survivor区的tospace区,若是还有存活对象,就会被复制到老年代。

7)老年代:在年轻代中通过GC后还存活的对象会被复制到老年代中,当老年代空间不足时,JVM会对老年代进行彻底的垃圾回收(full GC)。若是GC以后,仍是没法存放从survivor区复制的对象,就会出现内存溢出OOM(out of memory)

8)永久代:也称为方法区,存放静态类型数据,好比类,方法,属性等。

 

根据控制台报错:java.lang.OutOfMemoryError: PermGen space ---- PermGen space(永久保存区内存溢出)

permgen space全称是permanent generation space,指内存的永久保留区域;

此内存溢出缘由是这块内存主要被JVM存放class和meta信息,class在被load的时候被放入permgen space区域;permgen space区域与存放instance的heap区域不一样,GC不会在主程序运行期间对permgen space进行清理;因此,若是APP会载入不少class的话,极可能会出现permgen space溢出。

解决方法:手动设置MaxPermSize大小。

总结来讲:Tomcat在JVM上运行时,Tomcat可能加载了不少class,可是在运行期间GC不会回收此永久保存区内存,因此permgen space只会一直增大,直到达到指定的最大的XX:PermSize值,而后就出现了内存溢出状况,由于是测试环境,想要在测试时让应用稳定运行,将XX:MaxPermSize值设置稍微偏大,能够观察在两次开启Tomcat服务时间段以内大概会用到多少永久保存区的内存,而后进行设置,便可保障服务稳定运行。

在Tomcat家目录下的bin下有个catalina.bat配置文件,在其中设置内存:

JAVA_OPTS="-server -Xms512m -Xmx2048m -XX:PermSize=128m -XX:MaxNewSize=256m -XX:MaxPermSize=512m"

附(Tomcat自带状态页面):

相关文章
相关标签/搜索