tomcat和jvm调优

摘要:
为了解决此类问题,现代CPU引入了MMU。java–Xmx3550m–Xms3550m–Xmn2g–Xss128k–XX:ParallelGCThreads=20–XX:+UseConcMarkSweepGC–XX:+UseParNewGC–XX:+SurvivorRatio=8–XX:TargetSurvivorRatio=90–XX:MaxTenuringThreshold=31–XX:ParallelGCThreads=20:设置20个线程进行垃圾回收;–XX:+UseParNewGC:年轻代使用并行回收器;–XX:+UseConcMarkSweepGC:年老代使用CMS收集器降低停顿;–XX:+SurvivorRatio:设置Eden区和Survivor区的比例为8:1。–XX:TargetSurvivorRatio=90:设置Survivor区的可使用率。默认值是15次,即对象经过15次MinorGC依然存活,则进入年老代。除此之外可以性能调优在CPU负载不足的同时,偶尔会有用户反映请求的时间过长,意识到必须对程序及JVM进行调优。

一、tomcat的优化
Tomcat优化其实就是对server.xml优化(开户线程池,调整http connector参数)
executor="tomcatThreadPool" // 开启线程池
protocol="org.apache.coyote.http11. Http11AprProtocol" //开启Apr协议,需要安装Apr支持 (ip -> mac ip处于第三层,通过IP提供第二层mac)
enableLookups="false" // 关闭反向查询
compression="on" compressionMinSize="4096" // 开启静态文件压缩
noCompressionUserAgents="gozilla, traviata" //开启静态文件压缩
compressableMimeType="text/html,text/xml,text/javascript,text/css,text/plain,application/json,application/x-javascript" //开启静态文件压缩

二、对catalina.sh优化JVM
Tomcat路径incatalina.sh
平常在运行使用系统经常会报内存溢出的错误,内存溢出也叫OOM 会在catalina.sh加入
set JAVA_OPTS=-server -Xms1024m -Xmx2048m -XX:PermSize=256m -XX:MaxPermSize=512m // -Xms=-Xmx=服务器内存*70%
大对象出现在年轻代很可能扰乱年轻代 GC,并破坏年轻代原有的对象结构。因为尝试在年轻代分配大对象,很可能导致空间不足,为了有足够的空间容纳大对象,JVM 不得不将年轻代中的年轻对象挪到年老代
因为大对象占用空间多,所以可能需要移动大量小的年轻对象进入年老代,这对 GC 相当不利。尽可能避免使用短命的大对象。可以使用参数-XX:PetenureSizeThreshold 设置大对象直接进入年老代的阈值。当对象的大小超过这个值时,将直接在年老代分配。参数-XX:PetenureSizeThreshold 只对串行收集器和年轻代并行收集器有效,并行回收收集器不识别这个参数。
尝试使用大的内存分页
CPU 是通过寻址来访问内存的。32 位 CPU 的寻址宽度是 0~0xFFFFFFFF ,计算后得到的大小是 4G,也就是说可支持的物理内存最大是 4G。但在实践过程中,碰到了这样的问题,程序需要使用 4G 内存,而可用物理内存小于 4G,导致程序不得不降低内存占用。为了解决此类问题,现代 CPU 引入了 MMU(Memory Management Unit 内存管理单元)。MMU 的核心思想是利用虚拟地址替代物理地址,即 CPU 寻址时使用虚址,由 MMU 负责将虚址映射为物理地址。MMU 的引入,解决了对物理内存的限制,对程序来说,就像自己在使用 4G 内存一样。内存分页 (Paging) 是在使用 MMU 的基础上,提出的一种内存管理机制。它将虚拟地址和物理地址按固定大小(4K)分割成页 (page) 和页帧 (page frame),并保证页与页帧的大小相同。这种机制,从数据结构上,保证了访问内存的高效,并使 OS 能支持非连续性的内存分配。在程序内存不够用时,还可以将不常用的物理内存页转移到其他存储设备上,比如磁盘,这就是大家耳熟能详的虚拟内存
在 Solaris 系统中,JVM 可以支持 Large Page Size 的使用。使用大的内存分页可以增强 CPU 的内存寻址能力,从而提升系统的性能。
java –Xmx2506m –Xms2506m –Xmn1536m –Xss128k –XX:++UseParallelGC
–XX:ParallelGCThreads=20 –XX:+UseParallelOldGC –XX:+LargePageSizeInBytes=256m
–XX:+LargePageSizeInBytes:设置大页的大小。

过大的内存分页会导致 JVM 在计算 Heap 内部分区(perm, new, old)内存占用比例时,会出现超出正常值的划分,最坏情况下某个区会多占用一个页的大小。
使用非占有的垃圾回收器
为降低应用软件的垃圾回收时的停顿,首先考虑的是使用关注系统停顿的 CMS 回收器,其次,为了减少 Full GC 次数,应尽可能将对象预留在年轻代,因为年轻代 Minor GC 的成本远远小于年老代的 Full GC。
java –Xmx3550m –Xms3550m –Xmn2g –Xss128k –XX:ParallelGCThreads=20
–XX:+UseConcMarkSweepGC –XX:+UseParNewGC –XX:+SurvivorRatio=8 –XX:TargetSurvivorRatio=90
–XX:MaxTenuringThreshold=31
–XX:ParallelGCThreads=20:设置 20 个线程进行垃圾回收;

–XX:+UseParNewGC:年轻代使用并行回收器;

–XX:+UseConcMarkSweepGC:年老代使用 CMS 收集器降低停顿;

–XX:+SurvivorRatio:设置 Eden 区和 Survivor 区的比例为 8:1。稍大的 Survivor 空间可以提高在年轻代回收生命周期较短的对象的可能性,如果 Survivor 不够大,一些短命的对象可能直接进入年老代,这对系统来说是不利的。

–XX:TargetSurvivorRatio=90:设置 Survivor 区的可使用率。这里设置为 90%,则允许 90%的 Survivor 空间被使用。默认值是 50%。故该设置提高了 Survivor 区的使用率。当存放的对象超过这个百分比,则对象会向年老代压缩。因此,这个选项更有助于将对象留在年轻代。

–XX:MaxTenuringThreshold:设置年轻对象晋升到年老代的年龄。默认值是 15 次,即对象经过 15 次 Minor GC 依然存活,则进入年老代。这里设置为 31,目的是让对象尽可能地保存在年轻代区域。
除此之外可以性能调优
在CPU负载不足的同时,偶尔会有用户反映请求的时间过长,意识到必须对程序及JVM进行调优。从以下几个方面进行:
线程池:解决用户响应时间长的问题
连接池:链接时长和连接数 等
JVM启动参数:调整各代的内存比例和垃圾回收算法,提高吞吐量
程序算法:改进程序逻辑算法提高性能

一切都是为了这一步,调优,在调优之前,需要记住下面的原则:
1、多数的Java应用不需要在服务器上进行GC优化;
2、多数导致GC问题的Java应用,都不是因为我们参数设置错误,而是代码问题;
3、在应用上线之前,先考虑将机器的JVM参数设置到最优(最适合);
4、减少创建对象的数量;
5、减少使用全局变量和大对象,动态代理等
6、GC优化是到最后不得已才采用的手段;
7、在实际使用中,分析GC情况优化代码比优化GC参数要多得多
GC优化的目的有两个
1、将转移到老年代的对象数量降低到最小;
2、减少full GC的执行时间;
为了达到上面的目的,一般地,你需要做的事情有:
1、减少使用全局变量和大对象;
2、调整新生代的大小到最合适;
3、设置老年代的大小为最合适;
4、选择合适的GC收集器;
进行监控和调优
1、监控GC的状态
2、GC频率不高,GC耗时不高,那么没有必要进行GC优化;如果GC时间超过1-3秒,或者频繁GC,则必须优化

免责声明:文章转载自《tomcat和jvm调优》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇性能测试平台nGrinder当前几个主要的Lucene中文分词器的比较下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

ulimit设置内存限制是否有效

如何使用ulimit限制物理内存 限制物理内存 $ ulimit -m 512000 经测试,无效。 限制物理内存不起作用,ulimit不支持限制物理内存,可见man ulimit手册 -m The maximum resident set size (many systems do not honor this limit) 限制虚拟内存 $ ulim...

【JVM】CPU飙升问题

前言  线上程序突然CPU飙升,,,在一个并发不大的网站,这种情况基本上99.99%都是程序有死循环。接下来看看怎么具体定位排查吧。 硬啃 看看最近的代码,搜索关键字while,根据我多年临床经验,100%是哪位菜鸟写了bug。 如果找不到原因,继续往下看。 线程dump 1、找出java的进程id jps -l 2、通过进程id找到进程中各个线程的情况...

linux free 命令

free 命令显示系统内存的使用情况,包括物理内存、交换内存(swap)和内核缓冲区内存。 如果加上 -h 选项,输出的结果会友好很多: 有时我们需要持续的观察内存的状况,此时可以使用 -s 选项并指定间隔的秒数: $ free -h -s 3 上面的命令每隔 3 秒输出一次内存的使用情况,直到你按下 ctrl + c。(Ubuntu 16.04 中...

JAVA基础-栈与堆,static、final修饰符、内部类和Java内存分配

Java栈与堆 堆:顺序随意 栈:后进先出(Last-in/First-Out). Java的堆是一个运行时数据区,类的对象从中分配空间。这些对象通过new、newarray、anewarray和multianewarray等指令建立,它们不需要程序代码来显式的释放。堆是由垃圾回收来负责的,堆的优势是可以动态地分配内存大小,生存期也不必事先告诉编译器,因为...

启动tomcat时报内存溢出,Exception: java.lang.OutOfMemoryError thrown from the UncaughtExceptionHandler in thread "main"

文章转载自https://www.cnblogs.com/Chiler/p/9484266.html 问题原因   通过tomcat启动项目,也许是因为项目太大,配置的内存不够用了。老是报内存溢出的问题。 解决办法 1.选中项目 右键 run as -》Run Configurations... 2.出现tomcat配置页面。选中需要修改的tomcat...

java虚拟机启动参数分类详解

java启动参数共分为三类;其一是标准参数(-),所有的JVM实现都必须实现这些参数的功能,而且向后兼容;其二是非标准参数(-X),默认jvm实现这些参数的功能,但是并不保证所有jvm实现都满足,且不保证向后兼容;其三是非Stable参数(-XX),此类参数各个jvm实现会有所不同,将来可能会随时取消,需要慎重使用; 标准参数(-) verbose ...