Tomcat/JVM性能优化(也就PermGen排查啦)

最近一个SSH2项目升级了框架,部署后发现执行一段时间就会无法访问(Tomcat及其下其它Web可以正常访问)。

MyEclipse中进行“压力测试”时报错:Exception in thread "com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#0" java.lang.OutOfMemoryError: PermGen space

之后的现象跟测试机上部署的一样,初步判断就是这个原因。结合这个Exception,究其根本的原因,可能是框架第三方Jar包,class文件占有量变大;另一方面,有些模块请求历史数据时随着时间累积会返回较多的JSON数据,存放在Action的成员String变量中,通过Struts框架返回给前端,而前面说的这些,正好是存放在永久代(PermGen)里的。还有一个是测试部署的时候出现Exception loading sessions from persistent storage

java.io.WriteAbortedException: writing aborted; java.io.NotSerializableException: ... 当时的解决方法是相应的Bean继承Serializable接口,同时把work/Catalina/localhost/的项目文件夹给删了。总所周知,这个是jsp编译后的文件存放的目录,而PermGen OutOfMemoryError也容易发生在web服务器对JSP进行pre compile的时候。综上所述,那么就先看看PermGen的分配使用情况吧。

jstat内存监控(http://docs.oracle.com/javase/1.5.0/docs/tooldocs/share/jstat.html):

例如查看PermGen:jstat -gcpermcapacity pid

Windows上查看进程:tasklist | findstr javaw.exe

jstat内存监控出现pid not found:

在服务器上对部署的项目查看PermGen时,jstat出现pid not found的问题。jstat的基本原理是会生成一个hsperfdata_username的目录(里面存有pid文件,记录进程的信息),默认是在java.io.tmpdir目录下(linux上默认是/tmp下),但是我执行jstat的时候这个目录下没有pid文件。而网上资料说jdk1.6.0.23/24版本兼容性问题,而我正好使用了0.23,踩坑了。

While it‘s true that 6u23/24 introduce this issue, it‘s not a bug in jps. Rather a change in behavior of the VM itself. On GNU/Linux Jps and the likes seem to only look at /tmp but not necessarily your CATALINA_TMPDIR. If set or not, try to export CATALINA_TMPDIR=/tmp which translates to "-Djava.io.tmpdir=/tmp" and after restarting the Tomcat process you should see Tomcat‘s data as "/tmp/hsperfdata_/" and Jps will most likely work again as well.

解决办法是修改VM的配置文件,在tomcat/bin/catalina.sh中,找到CATALINA_TMPDIR,改为CATALINA_TMPDIR=/tmp,在重启tomcat就可以了。

继续在本地进行“压力测试”,结果出现问题时,PermGen的PGC/PC已被消耗光,YGC/FGC次数不断攀升,同时FGCT/GCT也持续增加,很明显,JVM尝试不断进行GC试图释放PermGen,但是似乎力不从心,导致程序一直被阻塞。那么,改PermGen参数咯。

更改Tomcat的JVM PermGen参数:

因为是本地MyEclipse以debug方式启动tomcat的,在按照网上所说的方法在%CATALINA_HOME%/bin/catalina.bat中Execute The Requested Command后增加set JAVA_OPTS=%JAVA_OPTS%-server -XX:PermSize=128m -XX:MaxPermSize=256m后,debug启动无效,其实这个时候tomcat是被调用tomcat7.exe启动,所以无法使得catalina.bat中的参数生效。

正确的方式是在MyEclipse -> Preferences -> Servers -> Tomcat -> Tomcat x.x -> JDK的Optional Java VM arguments中增加

-XX:PermSize=128M

-XX:MaxPermSize=256M

再启动即可。

本来PermSize设置为64M,Web项目启动执行过程中,如果不够用时它会按照某种方式增量分配,比如FGC一下,PGC/PC增到140M,接下来还会适时地FGC,又减到135M、130M之类。这样多累啊,不如初始分配时多一点,分配128M咯,然后再测试,执行时观察过程中并没有发生FGC。

就这样?其实我也想从代码上进行优化,以提高内存利用率,排除可能存在的内存泄露之类的问题。但是老代码太多(问题是升级过程中,大部分代码并未动过,只是新增了部分小模块),很怀疑是SSH框架(Spring3.2.1、Struts2.3.4、Hibernate3.3.2)的问题。这方面,大家有经验的请多指教。平常关注业务,都没时间去挖掘技术细节了。。。

时间: 2024-10-07 02:42:14

Tomcat/JVM性能优化(也就PermGen排查啦)的相关文章

一文学会JVM性能优化

实战性能优化 1 重新认知JVM 之前我们画过一张图,是从Class文件到类装载器,再到运行时数据区的过程,现在咱们把这张图不妨丰富完善一下,展示了JVM的大体物理结构图. 执行引擎:用于执行JVM字节码指令 主要由两种实现方式: (1)将输入的字节码指令在加载时或执行时翻译成另外一种虚拟机指令: (2)将输入的字节码指令在加载时或执行时翻译成宿主主机本地CPU的指令集.这两种方式对应着字节码的解释执行和即时编译. 9.2 堆内存溢出 9.2.1 代码 记得设置参数比如-Xmx20M -Xms2

JVM性能优化,第2部分:编译器JVM

通过优锐课的java学习分享中,整理了部分关于JVM的相关知识点,分享给大家参考学习,如有不足之处,欢迎 补充! Java编译器在JVM性能优化系列的第二篇文章中占据中心位置. Eva Andreasson介绍了不同种类的编译器,并比较了客户端,服务器和分层编译的性能结果.最后,她概述了常见的JVM优化,例如消除死代码,内联和循环优化. Java编译器是Java著名的平台的独立性的来源.软件开发人员会尽力编写最好的Java应用程序,然后编译器会在幕后进行工作,以为目标目标平台生成高效且性能良好的

jvm性能优化及内存分区

jvm性能优化及内存分区 2012-09-17 15:51:37 分类: Java Some of the default values for Sun JVMs are listed below. JDK 1.3.1_06 Initial Size Maximum Size Client JVM 1MB 32MB Server JVM 1MB 64MB JDK 1.4.1_01 Initial Size Maximum Size Client JVM 4MB 64MB Server JVM 4

JVM性能优化, Part 5:Java的伸缩性

ImportNew注: JVM性能优化系列文章前4篇由ImportNew翻译(第一篇,第二篇,第三篇, 第四篇).本文由新浪微博:吴杰 (@WildJay) 投稿至ImportNew.感谢吴杰! 如果你希望分享好的原创文章或者译文,欢迎投稿到ImportNew. 很多程序员在解决JVM性能问题的时候,花开了很多时间去调优应用程序级别的性能瓶颈,当你读完这本系列文章之后你会发现我可能更加系统地看待这类的问题.我说过JVM的自身技术限制了Java企业级应用的伸缩性.首先我们先列举一些主导因素. l

redmine在linux上的mysql性能优化方法与问题排查方案

iredmine的linux服务器mysql性能优化方法与问题排查方案 问题定位: 客户端工具: 1. 浏览器inspect-tool的network timing工具分析 2. 浏览器查看 response header, 分析http server 与 web server.       服务器工具:   0. nmon 查看各类系统负载, rrdtool 查看网络状况.   1. uptime看cpu负载;    free看内存;  mem ; cat /proc/meminfo以及  i

JAVA开发之大型互联网企业高并发架构Tomcat服务器性能优化视频教程

课程目标熟练掌握高并发架构Tomcat服务器性能优化. 适用人群对计算机,java开发人员,Java架构师,运维感兴趣的朋友! 课程简介Tomcat是Apache软件基金会(Apache Software Foundation)的Jakarta 项目中的一个核心项目,由Apache.Sun和其他一些公司及个人共同开发而成.Tomcat服务器是一个免费的开放源代码的Web应用服务器,属于轻量级应用服务器,在中小型系统和并发访问用户不是很多的场合下被普遍使用,是开发和调试JSP程序的首选. Tomc

JVM性能优化, Part 2 ―― 编译器

作为JVM性能优化系列文章的第2篇,本文将着重介绍Java编译器,此外还将对JIT编译器常用的一些优化措施进行讨论(参见"JVM性能优化,Part 1″中对JVM的介绍).Eva Andreasson将对不同种类的编译器做介绍,并比较客户端.服务器端和层次编译产生的编译结果在性能上的区别,此外将对通用的JVM优化做介绍,包括死代码剔除.内联以及循环优化. Java编译器存在是Java编程语言能独立于平台的根本原因.软件开发者可以尽全力编写程序,然后由Java编译器将源代码编译为针对于特定平台的高

Tomcat7调优及JVM性能优化for Linux环境

   该优化针对Linux X86_X64环境 Tomcat的三种模式及并发优化 Tomcat的运行模式有3种 1. bio 默认的模式,性能非常低下,没有经过任何优化处理和支持. 2. nio 利用java的异步io护理技术,noblocking IO技术 想运行在该模式下,直接修改server.xml里的Connector节点,修改protocol为 <Connector port="80″ protocol="org.apache.coyote.http11.Http11N

JVM性能优化,提高Java的伸缩性

很多程序员在解决JVM性能问题的时候,花开了很多时间去调优应用程序级别的性能瓶颈,当你读完这本系列文章之后你会发现我可能更加系统地看待这类的问题.我说过JVM的自身技术限制了Java企业级应用的伸缩性.首先我们先列举一些主导因素. 主流的硬件服务器提供了大量的内存 分布式系统有大量内存的需求,而且该需求在持续增长 一个普通Java应用程序所持有的对空间大概在1GB~4GB,这远远低于一个硬件服务器的内存管理能力以及一个分布式应用程序的内存需求量.这被称之为Java内存墙,如下图所示(图中表述Ja