讨论:TOMCAT一直内存溢出,有什么好的解决办法(顶者有分)

antony0203 2008-01-15 09:51:16
我们的系统正式上线后,使用人一多,就经常down掉。出现的情况是点击网页,要么就是打不开,要么就是打开页面后,登不进去
查看服务器进程,java内存和cpu个占用百分之十几。
tomcat无法用./shutdown.sh去停掉服务,只能kill进程
查看日志,经常有内存溢出
溢出原因大多不相同,贴一些log如下
1月14号的
Exception in thread "Timer-0" java.lang.OutOfMemoryError: Java heap space
at oracle.jdbc.dbaccess.DBItem.clone(DBItem.java:153)
at oracle.jdbc.dbaccess.DBDataSetImpl._setRowItems(DBDataSetImpl.java:912)
at oracle.jdbc.dbaccess.DBDataSetImpl._definesRowCompleted(DBDataSetImpl.java:1116)
at oracle.jdbc.dbaccess.DBDataSetImpl.rowCompleted(DBDataSetImpl.java:2362)
at oracle.jdbc.driver.OracleStatement.doDefinesFromTypes(OracleStatement.java:1094)
at oracle.jdbc.driver.OracleStatement.doExecuteQuery(OracleStatement.java:2396)
at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:2672)
at oracle.jdbc.driver.OraclePreparedStatement.executeUpdate(OraclePreparedStatement.java:589)
at oracle.jdbc.driver.OraclePreparedStatement.executeQuery(OraclePreparedStatement.java:527)
at org.apache.commons.dbcp.DelegatingPreparedStatement.executeQuery(DelegatingPreparedStatement.java:92)
at com.cea.security.web.listener.JavaTask.executeShedule(JavaTask.java:85)
at com.cea.security.web.listener.JavaTask.run(JavaTask.java:46)
at java.util.TimerThread.mainLoop(Unknown Source)
at java.util.TimerThread.run(Unknown Source)
2008-1-14 16:42:15 org.apache.tomcat.util.threads.ThreadPool$ControlRunnable run
严重: Caught exception (java.lang.OutOfMemoryError: Java heap space) executing org.apache.tomcat.util.net.LeaderFollowerWorkerThread@274d1c, terminating thread
DEBUG (loger.java:49) - 2008-01-14 16:42:42 fullURI: /safeweb/login.jsp
DEBUG (loger.java:49) - 2008-01-14 16:35:124 fullURI: /safeweb/login.jsp
2008-1-14 16:42:15 org.apache.tomcat.util.threads.ThreadPool$ControlRunnable run
严重: Caught exception (java.lang.OutOfMemoryError: Java heap space) executing org.apache.tomcat.util.net.LeaderFollowerWorkerThread@274d1c, terminating thread

1月10号
2008-1-10 16:37:29 org.apache.tomcat.util.threads.ThreadPool$ControlRunnable run
严重: Caught exception (java.lang.OutOfMemoryError: GC overhead limit exceeded) executing org.apache.tomcat.util.net.LeaderFollowerWorkerThread@1715ab5, terminating thread
....
2008-1-10 17:56:58 org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor processChildren
严重: Exception invoking periodic operation:
java.lang.OutOfMemoryError: Java heap space
2008-1-10 18:36:24 org.apache.tomcat.util.threads.ThreadPool$ControlRunnable run
严重: Caught exception (java.lang.OutOfMemoryError: Java heap space) executing org.apache.tomcat.util.net.LeaderFollowerWorkerThread@1715ab5, terminating thread
2008-1-10 18:36:24 org.apache.tomcat.util.threads.ThreadPool$ControlRunnable run
严重: Caught exception (java.lang.OutOfMemoryError: Java heap space) executing org.apache.tomcat.util.net.LeaderFollowerWorkerThread@1715ab5, terminating thread
java.lang.OutOfMemoryError: Java heap space
2008-1-10 19:05:55 org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor processChildren
严重: Exception invoking periodic operation:
java.lang.OutOfMemoryError: Java heap space
Exception in thread "http-8080-Processor296" 2008-1-10 20:01:26 org.apache.tomcat.util.threads.ThreadPool$ControlRunnable run
严重: Caught exception (java.lang.OutOfMemoryError: Java heap space) executing org.apache.tomcat.util.net.LeaderFollowerWorkerThread@1715ab5, terminating thread
2008-1-10 20:01:26 org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor processChildren
严重: Exception invoking periodic operation:
java.lang.OutOfMemoryError: Java heap space
2008-1-10 20:01:26 org.apache.tomcat.util.net.PoolTcpEndpoint processSocket
严重: Unexpected error processing socket
java.lang.OutOfMemoryError: Java heap space
java.lang.OutOfMemoryError: Java heap space
2008-1-10 20:14:07 org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor processChildren
严重: Exception invoking periodic operation:
java.lang.OutOfMemoryError: Java heap space
java.lang.OutOfMemoryError: Java heap space
2008-1-10 20:14:07 org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor processChildren
严重: Exception invoking periodic operation:
java.lang.OutOfMemoryError: Java heap space

目前-Xms512m -Xmx1024m

我觉得可能是程序的问题,但是我们是在别人公司的半成品上开发的,另一个team他们用这个半成品开发的项目也是几乎每天要重起一次,所以很可能问题在那家公司的那个平台上,而且就算是我们写的代码问题,现在去修改代码也不现实。最好有什么其它的解决方法。

网上也搜到几种方法,
一个是
写个脚本当tomcat使用的内存到一定比率时就自动重启它;设置为10分钟运行一次。

代码:
#!/bin/sh
#允许最大占用内存的百分比
ram_max=45
#服务程序所守候的端口
port=8180
#通过守候端口获取服务程序的pid
pid_ram=` netstat -nlp |grep $port|awk ’{ print }’|awk -F / ’{ print }’ `

#通过服务程序的pid获取当前占用的内存百分比
ram=` ps -aux |grep -m1 $pid_ram|awk ’{ print }’|awk -F . ’{ print }’ `

#调试程序用
#echo $port
#echo $pid_ram
#echo $ram
#echo $ram_max

#如果所占用的内存使用率大于所定义的值,则重启该服务程序
if expr $ram \>= $ram_max > /dev/null
then
#所要执行的动作
# echo 2
echo "8180 tomcat rebooted" >>/usr/local/tomcat-5.5.9/logs/autoreboot.log
echo `date` >>/usr/local/tomcat-5.5.9/logs/autoreboot.log
/usr/local/tomcat-5.5.9/bin/shutdown.sh
kill -9 $pid_ram
/usr/local/tomcat-5.5.9/bin/startup.sh

#调试程序用
#else
# echo 1
fi

第二个也是写个脚本
脚本方案:访问本机WEB;如果不响应就再试两次然后过滤出TOMCAT PID杀掉再重新启动TOMCAT。


这里各位有经验的朋友希望能发表你们的看法,提出更好的建议,谢啦!
...全文
4156 45 打赏 收藏 转发到动态 举报
写回复
用AI写文章
45 条回复
切换为时间正序
请发表友善的回复…
发表回复
Decmond 2011-11-25
  • 打赏
  • 举报
回复
我的一个项目中,也遇到了,是一个财务系统,是通过一个url来读取相应的数据,存储到相应的数据库表中,

生成了四个jar包,但其中jar包的xml配置的url 不同,其前三个是能够读取数据,但执行第四个jar包时,就出

现了楼主的问题,后来在cmd中执行了java -jar - Xmx1024m -Xms512m jar文件

这个应用是部在某所大学上的,其中第四个jar包执行时,会获取5W条的数据量。
vinalice 2011-06-09
  • 打赏
  • 举报
回复
可修改Catalina.bat里面的内存大小
antony0203 2008-02-03
  • 打赏
  • 举报
回复
问题还没解决,不过先结贴了
guoqiangone 2008-02-02
  • 打赏
  • 举报
回复
up
manlibie 2008-01-29
  • 打赏
  • 举报
回复
考虑并发的数量问题啊!
manlibie 2008-01-29
  • 打赏
  • 举报
回复
内存泄露问题
zdblzwj 2008-01-29
  • 打赏
  • 举报
回复
这么多人回答...
我也说点个人意见,前段时间公司一项目设计查询大量数据,造成数据库的CPU使用率过高,导致网页无法访问了,和你的问题好像有些出入,经高手指点我的问题可以用索引解决

帮顶...JF
guoqiangone 2008-01-29
  • 打赏
  • 举报
回复
session用的多吗?
注意session打开了要关闭
little06 2008-01-28
  • 打赏
  • 举报
回复
查看代码
加大tomcat使用的内存
用jprofile跟踪服务端,客户端压力测试
diamond_fish 2008-01-28
  • 打赏
  • 举报
回复
还有一个办法,lsof看看这个程序到底打开了哪些文件,可能读入了非常大的文件
ruanliang 2008-01-28
  • 打赏
  • 举报
回复
应该是写的程序查询量太大,冗余过多.检查下程序吧
消失风雨中 2008-01-28
  • 打赏
  • 举报
回复
在J道上看到过类似的问题,楼主可以去那看看
hxj1225 2008-01-25
  • 打赏
  • 举报
回复
是不是用完的链接没有关闭或者没有放回连接池?
hxj1225 2008-01-25
  • 打赏
  • 举报
回复
关注,学习
liuchuntao 2008-01-25
  • 打赏
  • 举报
回复
这种情况应该是程序有问题,建议检查程序代码。
antony0203 2008-01-23
  • 打赏
  • 举报
回复
请教个脚本
脚本方案:访问本机WEB;如果不响应就再试两次然后过滤出TOMCAT PID杀掉再重新启动TOMCAT。
或者是每天定时晚上12点重起

哪位熟悉脚本的教教我,谢了
gameboy911 2008-01-23
  • 打赏
  • 举报
回复
up
waterborn 2008-01-21
  • 打赏
  • 举报
回复
程序问题.
不用DBCP ,换C3P0 ,proxool 试试.
Ailen5 2008-01-21
  • 打赏
  • 举报
回复
1.数据库记录信息太多
2.方法中的session是否关闭
3.数据查询时,尽量不要全部查询出
antony0203 2008-01-21
  • 打赏
  • 举报
回复
有什么临时解决方法?
加载更多回复(22)
Tomcat内存溢出的三种情况及解决办法分析 Tomcat内存溢出的原因 在生产环境中tomcat内存设置不好很容易出现内存溢出。造成内存原因是不一样的,当然处理方式也不一样。 这里根据平时遇到的情况和相关资料进行一个总结。常见的一般会有下面三种情况: 1.OutOfMemoryError: Java heap space 2.OutOfMemoryError: PermGen space 3.OutOfMemoryError: unable to create new native thread. Tomcat内存溢出解决方案 对于前两种情况,在应用本身没有内存泄露的情况下可以用设置tomcat jvm参数来解决。(-Xms -Xmx -XX:PermSize -XX:MaxPermSize) 最后一种可能需要调整操作系统和tomcat jvm参数同时调整才能达到目的。 第一种:是堆溢出。 在JVM中如果98%的时间是用于GC且可用的 Heap size 不足2%的时候将抛出此异常信息。 没有内存泄露的情况下,调整-Xms -Xmx参数可以解决。 -Xms:初始堆大小 -Xmx:最大堆大小 但堆的大小受下面三方面影响: 1.相关操作系统的数据模型(32-bt还是64-bit)限制;(32位系统下,一般限制在1.5G~2G;我在2003 server 系统下(物理内存:4G和6G,jdk:1.6)测试 1612M,64为操作系统对内存无限制。) 2.系统的可用虚拟内存限制; 3.系统的可用物理内存限制。 堆的大小可以使用 java -Xmx***M version 命令来测试。支持的话会出现jdk的版本号,不支持会报错。 -Xms -Xmx一般配置成一样比较好比如set JAVA_OPTS= -Xms1024m -Xmx1024m 第二种:永久保存区域溢出 PermGen space的全称是Permanent Generation space,是指内存的永久保存区域。这一部分用于存放Class和Meta的信息,Class在被 Load的时候被放入PermGen space区域,它和和存放Instance的Heap区域不同,GC(Garbage Collection)不会在主程序运行期对PermGen space进行清理,所以如果你的APP会LOAD很多CLASS的话,就很可能出现PermGen space错误。这种错误常见在web服务器对JSP进行pre compile的时候。但目前的hibernate和spring项目中也很容易出现这样的问题。http://www.javaeye.com/topic/80620?page=1 的帖子有讨论的这个问题。可能是由于这些框架会动态class,而且jvm的gc是不会清理PemGen space的,导致内存溢出。 这一个一般是加大-XX:PermSize -XX:MaxPermSize 来解决问题。 -XX:PermSize 永久保存区域初始大小 -XX:PermSize 永久保存区域初始最大值 这一般结合第一条使用,比如 set JAVA_OPTS= -Xms1024m -Xmx1024m -XX:PermSize=128M -XX:PermSize=256M 有一点需要注意:java -Xmx***M version 命令来测试的最大堆内存是 -Xmx与 -XX:PermSize的 和 比如系统支持最大的jvm堆大小事1.5G,那 -Xmx1024m -XX:PermSize=768M 是无法运行的。 第三种:无法创建新的线程。 这种现象比较少见,也比较奇怪,主要是和jvm与系统内存的比例有关。 这种怪事是因为JVM已经被系统分配了大量的内存(比如1.5G),并且它至少要占用可用内存的一半。有人发现,在线程个数很多的情况下,你分配给JVM的内存越多,那么,上述错误发生的可能性就越大。 产生这种现象的原因如下(从这个blog中了解到原因:http://hi.baidu.com/hexiong/blog/item/16dc9e518fb10c2542a75b3c.html): 每一个32位的进程最多可以使用2G的可用内存,因为另外2G被操作系统保留。这里假设使用1.5G给JVM,那么还余下500M可用内存。这500M内存中的一部分必须用于系统dll的加载,那么真正剩下的也许只有400M,现在关键的地方出现了:当你使用Java创建一个线程,在JVM的内存里也会创建一个Thread对象,但是同时也会在操作系统里创建一个真正的物理线程(参考JVM规范),操作系统会在余下的400兆内存里创建这个物理线程,而不是在JVM的1500M的内存堆里创建。在jdk1.4里头,默认的栈大小是256KB,但是在jdk1.5里头,默认的栈大小为1M每线程,因此,在余下400M的可用内存里边我们最多也只能创建400个可用线程。 这样结论就出来了,要想创建更多的线程,你必须减少分配给JVM的最大内存。还有一种做法是让JVM宿主在你的JNI代码里边。 给出一个有关能够创建线程的最大个数的估算公式: (MaxProcessMemory - JVMMemory - ReservedOsMemory) / (ThreadStackSize) = Number of threads 对于jdk1.5而言,假设操作系统保留120M内存: 1.5GB JVM: (2GB-1.5Gb-120MB)/(1MB) = ~380 threads 1.0GB JVM: (2GB-1.0Gb-120MB)/(1MB) = ~880 threads 在2000/XP/2003的boot.ini里头有一个启动选项,好像是:/PAE /3G ,可以让用户进程最大内存扩充至3G,这时操作系统只能占用最多1G的虚存。那样应该可以让JVM创建更多的线程。 因此这种情况需要结合操作系统进行相关调整。 因此:我们需要结合不同情况对tomcat内存分配进行不同的诊断才能从根本上解决问题。 以上就是针对Tomcat内存溢出的几种解决方案。本文来自George的博客:《tomcat内存溢出总结》

67,513

社区成员

发帖
与我相关
我的任务
社区描述
J2EE只是Java企业应用。我们需要一个跨J2SE/WEB/EJB的微容器,保护我们的业务核心组件(中间件),以延续它的生命力,而不是依赖J2SE/J2EE版本。
社区管理员
  • Java EE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧