今天一个web服务器不工作了,查看日志.tomcat报出如下信息:
Caused by: java.lang.OutOfMemoryError: allocLargeArray - Object size: 80040, Num elements: 40010
以上日志信息基本的意思是程序要分配一个大小为 80040字节的数组(在JVM中数组也是对象,也是在heap中分配的),40010是指数组元素的多少。但是分配这个数组的时候, heap没有可用的空间了。
针对以上情况,解决办法如下:
A:调整java JVM参数,优化java虚拟机, 适当调大heap的 设置
B:清理系统无用日志,优apache运行参数. 打开gc日志以收集更多的heap使用信息.
关于java JVM的优化 ,更深入了解如下:
JVM内存的设置的原理
默认的java虚拟机的大小比较小,在对大数据进行处理时java就会报错 :java.lang.OutOfMemoryError。
设置jvm内存的方法,对于单独的.class,可以用下面的方法对Test运行时的jvm内存 进行设置。
java -Xms64m -Xmx256m Test
-Xms是设置内存初始化的大小
-Xmx是设置最大能够使用内存的大小(最 好不要超过物理内存大小)
在weblogic中,可以在startweblogic.cmd中对每个domain虚拟内存的大小进行设置,默认的 设置是在commEnv.cmd里面。
JVM内存的调优
1. Heap设定与垃圾回收Java Heap分为3个区,Young,Old和 Permanent。Young保存刚实例化的对象。当该区被填满时,GC会将对象移到Old区。Permanent区则负责保存反射对象,本文 不讨论该区。JVM的Heap分配可以使用-X参数设定,
-Xms: 初始Heap大小
-Xmx: java heap最大值
-Xmn: young generation的heap大小
JVM有2个GC线程。第一个线程负责回收Heap的Young区。第二个线程在Heap不足时,遍历 Heap,将Young 区升级为Older区。Older区的大小等于-Xmx减去-Xmn,不能将-Xms的值设的过大,因为第二个线程被迫运行 会降低JVM的性能。
为什么一些程序频繁发生GC?有如下原因:
l 程序内调用了 System.gc()或Runtime.gc()。
l 一些中间件软件调用自己的GC方法,此时需要设置参数 禁止这些GC。
l Java的Heap太小,一般默认的Heap值都很小。
l 频繁实例化对象,Release对象。此时尽量保存并重用对象,例如使用StringBuffer()和String()。
如果 你发现每次GC后,Heap的剩余空间会是总空间的50%,这表示你的Heap处于健康状态。
许多Server端的Java程序每次GC后 最好能有65%的剩余空间。经验之谈:
1.Server端JVM最好将-Xms和-Xmx设为相同值。为了优化GC,最好让-Xmn值约等于 -Xmx的1/3[2]。
2.一个GUI程序最好是每10到20秒间运行一次GC,每次在半秒之内完成[2]。