【生产环境】Tomcat运行一段时间后访问变慢分析历程

环境运行一天或者几天,网站访问就很卡,手机端app访问页面出现白屏。Tomcat运行一段时间后访问变慢,可是cpu,内存都正常。日志也是发现不了啥....java

问题的原先分析

1.环境配置(cpu,内存,使用工具:nmon工具、visualvm工具、jprofiler工具所有用上监控中)linux

2.修改info日志,启用error级别日志(待筛选排查)web

3.查看数据库配置链接池(正常)数据库

4.代码问题对象建立太多(待排查,web里面走拦截器待看)tomcat

5.jvm分配内存太少了(调优,生产环境重启)网络

6.并发高了,网站太多人访问(排除)多线程

7.webapps下面的工程太多了(排除)并发

8.数据压力太大数据盘大(排除)app

9.物理机器问题、网络宽度问题...less

Linux环境配置信息

Tomcat启动行参数的优化

修改前:

JAVA_OPTS="-Xmx2048m -Xms1024m -Xmn384M -XX:MaxPermSize=512m -XX:PermSize=128m"
进行重修调整,修改后:

JAVA_OPTS="-server -Xmx2048m -Xms2048m -Xmn384M -XX:PermSize=512m -XX:MaxPermSize=512m -Xss512k -XX:+AggressiveOpts -XX:+DisableExplicitGC -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:+CMSParallelRemarkEnabled -XX:+UseCMSCompactAtFullCollection -XX:+UseFastAccessorMethods -XX:+UseCMSInitiatingOccupancyOnly -XX:-UseGCOverheadLimit -XX:+HeapDumpOnOutOfMemoryError -XX:CMSInitiatingOccupancyFraction=75 -XX:CMSFullGCsBeforeCompaction=2 -XX:SoftRefLRUPolicyMSPerMB=0 -Djava.awt.headless=true "
参数解释:

-server :

tomcat是运行在生产环境中的,这个参数必须上,由于tomcat默认是以一种叫java –client的模式来运行的,server即意味着你的tomcat是以真实的production的模式在运行的,这也就意味着tomcat以server模式运行时将拥有:更大、更高的并发处理能力,更快更强捷的JVM垃圾回收机制,能够得到更多的负载与吞吐量更等

-Xmx2048m -Xms2048m

即JVM内存设置了,把Xms与Xmx两个值设成同样是最优的作法。存放 new MyClass() 的对象,是GC的主要区域,-Xms / -Xmx 分别是堆的初始容量、最大可扩展容量,建议初始值设置为最大值,以避免反复扩展或缩减的开销;

-Xmx2048m:设置JVM最大可用内存为2048M。
-Xms2048m:设置JVM促使内存为3550m。此值能够设置与-Xmx相同,以免每次垃圾回收完成后JVM从新分配内存。

-Xmn512m

设置年轻代大小为512m。整个堆大小=年轻代大小 + 年老代大小 + 持久代大小。持久代通常固定大小为64m,因此增大年轻代后,将会减少年老代大小。此值对系统性能影响较大,Sun官方推荐配置为整个堆的3/8。

-XX:PermSize=512m -XX:MaxPermSize=512m

JVM使用-XX:PermSize设置非堆内存初始值,默认是物理内存的1/64;在数据量的很大的文件导出时,必定要把这两个值设置上,不然会出现内存溢出的错误。由XX:MaxPermSize设置最大非堆内存的大小,默认是物理内存的1/4。那么,若是是物理内存4GB,那么64分之一就是64MB,这就是PermSize默认值,也就是永生代内存初始大小;四分之一是1024MB,这就是MaxPermSize默认大小。

-Xss512k

是指设定每一个线程的堆栈大小。这个就要依据你的程序,看一个线程 大约须要占用多少内存,可能会有多少线程同时运行等。通常不易设置超过1M,要否则容易出现out ofmemory。

设置每一个线程的堆栈大小。JDK5.0之后每一个线程堆栈大小为1M,之前每一个线程堆栈大小为256K。更具应用的线程所需内存大小进行调整。在相同物理内存下,减少这个值能生成更多的线程。可是操做系统对一个进程内的线程数仍是有限制的,不能无限生成,经验值在3000~5000左右。

-XX:+AggressiveOpts

做用如其名(aggressive),启用这个参数,则每当JDK版本升级时,你的JVM都会使用最新加入的优化技术(若是有的话)

-XX:+DisableExplicitGC

在程序代码中不容许有显示的调用”System.gc()”。看到过有两个极品工程中每次在DAO操做结束时手动调用System.gc()一下,以为这样作好像可以解决它们的out ofmemory问题同样,付出的代价就是系统响应时间严重下降,就和我在关于Xms,Xmx里的解释的原理同样,这样去调用GC致使系统的JVM大起大落,

-XX:+UseBiasedLocking

启用一个优化了的线程锁,咱们知道在咱们的appserver,每一个http请求就是一个线程,有的请求短有的请求长,就会有请求排队的现象,甚至还会出现线程阻塞,这个优化了的线程锁使得你的appserver内对线程处理自动进行最优调配。

-XX:MaxTenuringThreshold=31

设置垃圾最大年龄。若是设置为0的话,则年轻代对象不通过Survivor区,直接进入年老代。对于年老代比较多的应用,能够提升效率。若是将此值设置为一个较大值,则年轻代对象会在Survivor区进行屡次复制,这样能够增长对象再年轻代的存活时间,增长在年轻代即被回收的几率。这个值的设置是根据本地的jprofiler监控后获得的一个理想的值,不能一律而论原搬照抄。

-XX:+UseConcMarkSweepGC

即CMS gc,这一特性只有jdk1.5即后续版本才具备的功能,它使用的是gc估算触发和heap占用触发。咱们知道频频繁的GC会造面JVM的大起大落从而影响到系统的效率,所以使用了CMS GC后能够在GC次数增多的状况下,每次GC的响应时间却很短,好比说使用了CMS GC后通过jprofiler的观察,GC被触发次数很是多,而每次GC耗时仅为几毫秒。

-XX:+UseParNewGC 

对年轻代采用多线程并行回收,这样收得快。

-XX:+CMSParallelRemarkEnabled

在使用UseParNewGC 的状况下, 尽可能减小 mark 的时间

-XX:+UseCMSCompactAtFullCollection

在使用concurrent gc 的状况下, 防止 memoryfragmention, 对live object 进行整理, 使 memory 碎片减小。

-XX:LargePageSizeInBytes=128m  

指定 Java heap的分页页面大小

-XX:+UseFastAccessorMethods

get,set 方法转成本地代码

-XX:+UseCMSInitiatingOccupancyOnly

指示只有在 oldgeneration 在使用了初始化的比例后concurrent collector 启动收集

-XX:CMSInitiatingOccupancyFraction=70

CMSInitiatingOccupancyFraction,这个参数设置有很大技巧,基本上知足(Xmx-Xmn)(100- CMSInitiatingOccupancyFraction)/100>=Xmn就不会出现promotion failed。在个人应用中Xmx是6000,Xmn是512,那么Xmx-Xmn是5488兆,也就是年老代有5488 兆,CMSInitiatingOccupancyFraction=90说明年老代到90%满的时候开始执行对年老代的并发垃圾回收(CMS),这时还 剩10%的空间是548810%=548兆,因此即便Xmn(也就是年轻代共512兆)里全部对象都搬到年老代里,548兆的空间也足够了,因此只要满 足上面的公式,就不会出现垃圾回收时的promotion failed;

所以这个参数的设置必须与Xmn关联在一块儿。

-XX:-UseGCOverheadLimit

-XX:+HeapDumpOnOutOfMemoryError

-XX:CMSInitiatingOccupancyFraction=75

-XX:CMSFullGCsBeforeCompaction=2

-XX:SoftRefLRUPolicyMSPerMB=0

-Djava.awt.headless=true

这个参数通常咱们都是放在最后使用的,这全参数的做用是这样的,有时咱们会在咱们的J2EE工程中使用一些图表工具如:jfreechart,用于在web网页输出GIF/JPG等流,在winodws环境下,通常咱们的app server在输出图形时不会碰到什么问题,可是在linux/unix环境下常常会碰到一个exception致使你在winodws开发环境下图片显示的好好但是在linux/unix下却显示不出来,所以加上这个参数以避免避这样的状况出现。

-XX:+UseParallelOldGC

-XX:+PrintGCDateStamps

-XX:+PrintGCDetails

-Xloggc:/opt/lucky/app/lucky/tomcat/logs/gc.log

上述这样的配置,基本上能够达到:系统响应时间增快、JVM回收速度增快同时又不影响系统的响应率、JVM内存最大化利用、线程阻塞状况最小化。

Tomcat启动慢调整
JVM环境中解决:

打开vi $JAVA_HOME/jre/lib/security/java.security这个文件,找到下面的内容:

securerandom.source=file:/dev/urandom

替换成

securerandom.source=file:/dev/./urandom

 

代码模块进行

数据库查询语句进行

 

参考:

JVM调优总结 -Xms -Xmx -Xmn -Xss

http://unixboy.iteye.com/blog/174173

相关文章
相关标签/搜索