Tomcat 性能调优
Tomcat启动行参数(JVM)优化
1.文件定位:catalina.bat
2.参数添加
set JAVA_OPTS = %JAVA_OPTS% -server -Xms1028M -Xmx1028M
-Xmn385M -Xss128k -XX:PermSize=256M
参数解释
-server : 位置必须为第一个参数
默认情况下,tomcat以java -client模式运行,toncat以server模式运行会有更大,更高的并发处理能力;更快的JVM垃圾回收;更多的负载和吞吐量
l -Xms (1/64) -Xmx (1/4) : JVM内存设置
l 前提:在设置下最大内存时,检验JVM最大可用内存
l 方法:cmd java -Xmx150m -version
l tomcat启动时会以最小内存设置值启动
l 默认空余内存小于40%时,JVM会增大到-Xmx;
l 空余内存大于70%时,JVM会缩小到-Xms;
l 通常设置最大最小的值一样避免每次GC后调整堆的大小。
-Xmn : 年轻代大小
堆大小=年轻代大小(young generation) + 年老代大小(tenured generation) + 持久代大小(permanet generation)
GC常用的是分代收集。
增大年轻代后,将会减小年老代大小.此值对系统性能影响较大,
推荐配置为整个堆的3/8
l -Xmn : 年轻代大小
l 堆大小 = 年轻代大小(young generation) + 年老代大小(tenured generation) + 持久代大小(permanet generation)
l GC常用的是分代收集。
l 绝大部分的objec被分配在young generation(生命周期短),并且大部分的object在这里die。
l young generation满了之后,将引发minor collection(YGC)。在minor collection后存活的object会被移动到tenured generation(生命周期比较长)。
l tenured generation满之后触发major collection。major collection(Full gc)会触发整个heap的回收,包括回收young generation。
l permanet generation区域比较稳定,主要存放classloader信息。
l 增大年轻代后,将会减小年老代大小.此值对系统性能影响较大,
推荐配置为整个堆的3/8
young generation有eden、2个survivor 区域组成。其中一个survivor区域一直是空的,是eden区域和另一个survivor区域在下一次copy collection后活着的objecy的目的地。object在survivo区域被复制直到转移到tenured区。
我们要尽量减少 Full gc 的次数(tenured generation 一般比较大,收集的时间较长,频繁的Full gc会导致应用的性能收到严重的影响)。
-Xss : 每个线程的堆栈大小
一个线程占多少内存,多少线程同时运行,依程序而定
一般不超过 1M
-XX:+UseBiasedLocking :启动优化线程锁
每个http请求即一个线程,请求时间不定,出现请求排队现象,甚至线程阻塞
此配置使得服务器对线程处理自动进行最有配置
l -XX:PermSize(1/64)-XX:MaxPermSize(1/4):非堆内存
l JVM自己用的内存:方法区;内部处理;类结构;方法代码
l 这一部分内存用于存放Class和Meta的信息,Class在被 Load的时候被放入
l PermGen space区域,它和存放Instance的Heap区域不同。
l GC(Garbage Collection)不会在主程序运行期对PermGen space进行清理,
所以如果你的APP会LOAD很多CLASS 的话,就很可能出现PermGen space错误。
-XX:+UseParNewGC
-XX:+UseConcMarkSweepGC
-XX:MaxTenuringThreshold
-XX:+CMSParallelRemarkEnabled
-XX:+UseCMSCompactAtFullCollection
-XX:LargePageSizeInBytes
-XX:+UseFastAccessorMethods
-XX:+UseCMSInitiatingOccupancyOnly
-XX:CMSInitiatingOccupancyFraction
-Djava.awt.headless=true
内存申请过程
l JVM会试图为相关Java对象在Eden中初始化一块内存区域;
l 当Eden空间足够时,内存申请结束。否则到下一步;
l JVM试图释放在Eden中所有不活跃的对象(minor collection),释放后若Eden空间 仍然不足以放入新对象,则试图将部分Eden中活跃对象放入Survivor区;
l Survivor区被用来作为Eden及old的中间交换区域,当OLD区空间足够时,Survivor区的对象会被移到Old区,否则会被保留在Survivor区;
l 当old区空间不够时,JVM会在old区进行major collection;
l 完全垃圾收集后,若Survivor及old区仍然无法存放从Eden复制过来的部分对象,导致JVM无法在Eden区为新对象创建内存区域,则出现"Out of memory错误";
对象衰老过程
l 新创建的对象的内存都分配自eden。Minor collection的过程就是将eden和在用survivor space中的活对象copy到空闲survivor space中。对象在young generation里经历了一定次数(可以通过参数配置)的minor collection后,就会被移到old generation中,称为tenuring。
Tomcat容器内优化
1.文件定位:server.xml
2.参数添加
URIEncoding="UTF-8" minSpareThreads="25" maxSpareThreads="75"
enableLookups="false" disableUploadTimeout="true" connectionTimeout="20000" acceptCount="300" maxThreads="300" maxProcessors="1000" minProcessors="5" useURIValidationHack="false" compression="on" compressionMinSize="2048" compressableMimeType="text/html,text/xml,text/javascript,text/css,text/plain" redirectPort="8443"
参数解释
URIEncoding="UTF-8" :
解析含有中文名的文件的url
maxSpareThreads : 空闲状态的线程数
如果空闲状态的线程数多于设置的数目,则将这些线程终止,减少池中的线程总数
minSpareThreads : 最小备用线程数
tomcat启动时的初始化的线程数
maxThreads:最大并发数
Tomcat可创建的最大的线程数
acceptCount:等待队列的大小
acceptCount是当线程数达到maxThreads后,后续请求会被放入一个等待队列,
这个acceptCount是这个队列的大小,如果这个队列也满了,就直接refuse connection
useURIValidationHack
enableLookups="false"
disableUploadTimeout
gzip压缩(HTTP压缩)
监控(JDK的bin下的jconsole)
1.本机:直接监控则可以
1.非本机:指定ip,port
set JAVA_OPTS= %JAVA_OPTS% -Djava.rmi.server.hostname=192.168.1.17
set JAVA_OPTS= %JAVA_OPTS% -Dcom.sun.management.jmxremote.port=8888
set JAVA_OPTS= %JAVA_OPTS% -Dcom.sun.management.jmxremote.ssl=false
set JAVA_OPTS= %JAVA_OPTS% -Dcom.sun.management.jmxremote.authenticate=false
测试
org.apache.commons.httpclient包的类:
HttpClient ;HttpMethod 等
疑问?Perm区 栈 存放内容的区别?
l JVM堆的Perm区:
l 保存class,method,filed对象;存放Class和Meta信息,Class在被Load的时候被放入该区域Heap space:存放Instance
l GC(Garbage Collection)应该不会对PermGen space进行清理,所以如果你的APP会LOAD很多CLASS的话,就很可能出现PermGen space错误
l 栈:
l 当一个class文件被ClassLoader load进入JVM后,方法指令保存在Stack中
l java栈:
Java栈是与每一个线程关联的,JVM在创建每一个线程的时候,会分配一定的栈空间给线程。它主要用来存储线程执行过程中的局部变量,方法的返回值,以及方法调用上下文。栈空间随着线程的终止而释放。
参考
http://blog.csdn.net/lifetragedy/article/details/7708724
JVM参数设置demo :
http://www.cnblogs.com/redcreen/archive/2011/05/05/2038331.html
JVM内存分析 :
http://blog.csdn.net/pochuanpiao/article/details/8147805