JVM 内存问题 java.lang.OutOfMemoryError: PermGen spaceh 和内存分配问题INFO: error='Cannot allocate memory'

       公司知识库上线一段时间后,大约有200条数据,知识库采用JSP+Spring MVC+Hibernate+Spring+Lucene 数据库Mysql的技术框架,为了更大的法规知识库的作用,公司决定将已有的行业内信息,批量上传到知识库中,大约有1万左右数据,物理文件大约是1.6G,通过对数据的整理,达到批量上传的前提条件,经过编写批量处理代码后,实现了数据的上传,自动创建Lucene索引,创建后的indexfiles是根据文档的分类进行分类存储,总计有1648K,物理文件经过使用spring-web框架中的MultipartFile处理后,总计约20K,截止到这里,数据成功上传了,以为万事大吉了,事实上事与愿违,在使用知识库的过程中,不断的出现OOME或commit_memory failed,详细异常如下:

Exception in thread "ajp-bio-8009-exec-2" java.lang.OutOfMemoryError: PermGen space
Java HotSpot(TM) 64-Bit Server VM warning: Exception java.lang.OutOfMemoryError occurred dispatching signal SIGTERM to handler- the VM may need to be forcibly terminated
Error: Exception thrown by the agent : java.rmi.server.ExportException: Port already in use: 9090; nested exception is: 
	java.net.BindException: Address already in use
Exception in thread "ajp-bio-8009-exec-4" java.lang.OutOfMemoryError: PermGen space
Exception in thread "ajp-bio-8009-exec-6" java.lang.OutOfMemoryError: PermGen space
Java HotSpot(TM) 64-Bit Server VM warning: Exception java.lang.OutOfMemoryError occurred
dispatching signal SIGTERM to handler- the VM may need to be forcibly terminated
Exception in thread "ajp-bio-8009-exec-7" java.lang.OutOfMemoryError: PermGen space
Java HotSpot(TM) 64-Bit Server VM warning: INFO: os::commit_memory(0x00000007fe880000, 24641536, 0) failed; 
error='Cannot allocate memory' (errno=12)
#
# There is insufficient memory for the Java Runtime Environment to continue.
# Native memory allocation (malloc) failed to allocate 24641536 bytes for committing reserved memory.
# An error report file with more information is saved as:
# /usr/local/apache-tomcat-7.0.64/bin/hs_err_pid19666.log

于是通过工具进行远程监控Linux上的Tomcat以及在线监控Linux服务器资源占用情况:

监控Tomcat使用的jdk自带的Java VisualVM,在C:\Program Files\Java\jdk1.7.0_79\bin下可以找到相应的jvisualvm.exe文件,用的是不需要密码的,需要密码的话,则加上密码的配置和密码文件就可以了。

在tomcat bin目录下找到catalina.sh,打开,按照下面代码进行配置:

# OS specific support.  $var _must_ be set to either true or false.
CATALINA_HOME=/usr/local/apache-tomcat-7.0.64
JAVA_HOME=/usr/local/development/jdk1.7.0_79/
JAVA_OPTS="-XX:MaxPermSize=256m -Dcom.sun.management.jmxremote.port=9090 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -Djava.rmi.server.hostname=10.1.3.55" 
cygwin=false
darwin=false
os400=false
case "`uname`" in
CYGWIN*) cygwin=true;;
Darwin*) darwin=true;;
OS400*) os400=true;;
esac

配置后,重启tomcat即可,在window的可视化工具中,直接添加远程的JMX即可查看tomcat的运行情况,经过边操作系统,边监控发现,PermGen页签中的使用曲线逐渐的接近到JDK默认设置的大小,70M左右,达到最大值后,Tomcat出现了卡死现象,系统无法做任何操作,Linux中的Tomcat进程无法通过正常手段关闭,于是使用Kill -9 进程号,然后修改了catalina.sh,增加了JAVA_OPTS中的-XX:MaxPermSize=256m,这里只设置了最大值,最小值可以由JDK来控制。

对于第二个异常,查过网友遇到的,大多数是Tomcat运行一段时间,随机的出现的,不定时,我这次只不过不随机,操作一段时间后,就会出现这个问题,问题更加好重现和验证,然后经过查看Error日志中的log文件的hs_err_pid19666.log文件,其中说:

# Possible reasons:
#   The system is out of physical RAM or swap space  物理交换空间不够
#   In 32 bit mode, the process size limit was hit  线程数量受限制

经过查看,物理交换空间是4G足够了,然后使用ulimit -a或-n查看,值只有1024,将其修改增大,具体修改方法,可以参考以下这位朋友的方法, 亲测可用:

https://blog.csdn.net/KimSoft/article/details/8024216

你可能感兴趣的:(JVM)