收藏 分享(赏)

Tomcat中Java垃圾收集调优.doc

上传人:hskm5268 文档编号:6331683 上传时间:2019-04-07 格式:DOC 页数:5 大小:65.50KB
下载 相关 举报
Tomcat中Java垃圾收集调优.doc_第1页
第1页 / 共5页
Tomcat中Java垃圾收集调优.doc_第2页
第2页 / 共5页
Tomcat中Java垃圾收集调优.doc_第3页
第3页 / 共5页
Tomcat中Java垃圾收集调优.doc_第4页
第4页 / 共5页
Tomcat中Java垃圾收集调优.doc_第5页
第5页 / 共5页
亲,该文档总共5页,全部预览完了,如果喜欢就下载吧!
资源描述

1、Tomcat 中 Java 垃圾收集调优1 JVM 内存 JAVA_OPTS 参数说明设置服务器端的 JVM 参数一般在 catalina.bat 文件中:JAVA_OPTS=“-server -Xms2048m -Xmx2048m -Xss512k“ JVM 中对象的划分及管理介绍JVM 根据运行于其中的对象的生存时间大致的分为 3 种。并且将这 3 种不同的对象分别存放在 JVM 从系统分配到的不同的内存空间。这种对象存放空间的管理方式叫做 Generation 管理方式。1). Young Generation(年轻代):用于存放“早逝”对象(即瞬时对象) 。例如:在创建对象时或者调用方

2、法时使用的临时对象或局部变量。2). Tenured Generation(年老代):用于存放“驻留”对象(即较长时间被引用的对象) 。往往体现为一个大型程序中的全局对象或长时间被使用的对象。3). Perm Generation(永久保存区域):用于存放“永久”对象。这些对象管理着运行于 JVM 中的类和方法。-在命令行下用 java -XmxXXXXM -version 命令来测试 java 可用最大内存,测试可逐渐增大 XXXX 的值,如果执行正常就表示指定的内存大小可用,否则会打印错误信息。通常测试 windows 系统(32 位)最大内存为:1500M,但系统一般到 1280M 就差

3、不多了-关于垃圾收集分类介绍在 JVM 中有两种垃圾方式:1). 一种叫做 Minor(次收集) 。Minor 在 Young Generation(年轻代)的空间被对象全部占用后执行,主要是对 Young Generation 中的对象进行垃圾收集。2). 一种叫做 Major(主收集) 。Major 是针对于整个 Heap size(Xms 和 Xmx 设置为 JVM 使用的内存,但不包括永久保存区域使用的内存)的垃圾收集。其中 Minor 方式的收集经常发生,并且 Minor 收集所占用的系统时间小。而 Major 方式的垃圾收集则是一种“昂贵”的垃圾收集方式,因为在 Major 要对整

4、个 Heap size 进行垃圾收集,这会使得应用停顿的时间变得较长。关于 TOMCAT 内存占用介绍Tomcat 运行占用内存= Xmx 占用的内存 + Perm Generation(永久保存区域)占用内存 + 所有 Java 应用创建线程数 x 1MJava 应用每创建一个线程,在 JVM 的内存里也会创建一个 Thread 对象,但是同时也会在操作系统里创建一个真正的物理线程(参考 JVM 规范) ,操作系统会在 TOMCAT 余下的内存里创建这个物理线程,而不是在 JVM 的 Xmx 设置的内存堆里创建。在 jdk1.4 里头,默认的栈大小是 256KB,但是在 jdk1.5 里头,

5、默认的栈大小为 1M 每线程。因此,如果系统剩余内存为 400M 的可用内存,则 Java 应用最多创建 400 个可用线程。结论:要想创建更多的线程,必须减少分配给 JVM 的最大内存。参数说明如下:-server:一定要作为第一个参数,在多个 CPU 时性能佳 -Xms:初始 Heap 大小,使用的最小内存,cpu 性能高时此值应设的大一些 -Xmx:java heap 最大值,使用的最大内存 上面两个值是分配 JVM 的最小和最大内存,取决于硬件物理内存的大小,建议均设为物理内存的一半,最大不要超过可用物理内存的 80。 -Xmn:young generation(年轻代)的 heap

6、大小,一般设置为 Xmx 的 3、4 分之一(此值对系统性能影响较大,Sun 官方推荐配置为整个堆的 3/8)(可使用-XX:NewSize 和-XX:MaxNewsize 设置年轻代的初始值和最大值)-Xincgc :启动增量垃圾收集器,缺省是关闭的。增量垃圾收集器能减少偶然发生的长时间的垃圾回收造成的暂停时间。但增量垃圾收集器和应用程序并发执行,因此会占用部分 CPU 在应用程序上的功能。-XX:CMSInitiatingOccupancyFraction=70 发现引起 promotion failed 错误的原因是 CMS 来不及回收(CMS 默认在年老代占到 90%左右才会执行) ,

7、年老代又没有足够的空间供 GC 把一些活的对象从年轻代移到年老代,所以执行 Full GC。CMSInitiatingOccupancyFraction=70 表示年老代占到约 70%时就开始执行 CMS,这样就不会频繁出现 Full GC 了。上两个参数设置有很大技巧,基本上满足:(Xmx-Xmn)*(100- CMSInitiatingOccupancyFraction)/100=Xmn 就不会出现 promotion failed。如果在应用中设置 Xmx(最大内存)是 1500m,Xmn(年轻代)是 340m,那么 Xmx-Xmn 是 1160m,也就是年老代有 1160 兆,CMSI

8、nitiatingOccupancyFraction=70 说明年老代到 70%满的时候开始执行对年老代的并发垃圾回收(CMS) ,这时还剩 30%的空间是 1160*30%=348 兆,所以即使 Xmn(也就是年轻代共 340兆)里所有对象都搬到年老代里,348 兆的空间也足够了,所以只要满足上面的公式,就不会出现垃圾回收时的 promotion failed -XX:PermSize= xxxm:设定 xxx 兆内存的永久保存区域-XX:MaxPermSize=xxxm:设定 xxx 兆最大内存的永久保存区域 PermSize 和 MaxPermSize 指明虚拟机为 java 永久生成对

9、象(Permanate generation)如,class 对象、方法对象这些可反射(reflective)对象分配内存限制,这些内存不包括在 Heap(堆内存)区之中。上述参数如果不设定,永久保存区域默认大小:-server 选项下默认 MaxPermSize 为 64m,-client 选项下默认 MaxPermSize 为 32m。运行程序时,jvm 会调整永久保存区域的大小以满足需要。每次调整时,jvm 会对堆进行一次完全的垃圾收集。-XX:+UseConcMarkSweepGC :选择 CMS 收集器(并发回收,缩短 major 收集的时间) 提示:此选项在 Heap Size 比

10、较大而且 Major 收集时间较长的情况下使用更合适。【-XX:+UseParNewGC :对年轻代采用多线程并行回收,这样收得快(缩短 minor 收集的时间,如果设置-XX:+UseConcMarkSweepGC,无须设置-XX:+UseParNewGC,是默认的) 】-XX:MaxTenuringThreshold=5 CMS 收集器中,新生代对象撑过过多少次 minor gc 才进入年老代的。默认为 0(或另一说法:一个对象如果在救助空间移动 5 次还没有被回收就放入年老代) 。如果设置为 0就是去掉了新生代空间,存活的临时对象不经过 Survivor 区直接进入年老代,不久就占满年老

11、代发生 full gc-XX:GCTimeRatio=19 表示 java 可以用 5%的时间来做垃圾回收,1/(1+19)=1 /20=5%-XX:CMSFullGCsBeforeCompaction=N 表示执行 N 次 Full GC 后执行内存压缩,免得产生内存碎片(案例都设置为:-XX:CMSFullGCsBeforeCompaction=0)-XX:+UseCMSCompactAtFullCollection:表示执行 Full GC 后对内存进行整理压缩,免得产生内存碎片-Xnoclassgc:禁用类垃圾回收,性能会高一点;-verbose:gc 显示垃圾收集信息 (在虚拟机发生

12、内存回收时在输出设备显示信息)-Xloggc:gc.log 指定垃圾收集日志文件 -XX:+DisableExplicitGC 禁止 System.gc():免得程序员误调用 gc 方法影响性能;-XX:+ExplicitGCInvokesConcurrent:System.gc()可以与应用程序并发执行。(System.gc()来收回不用的内存,是写在程序里的。System.gc()只是“建议”JVM 回收内存,不是强制。禁止 System.gc()要看实际开发的程序如何处理。因此编程要养成习惯,创建一个对象,不再用时指向 null,这样 jvm 发现它不再使用时,会更早的把它放进回收队列,

13、才能更早的进行回收。例如:你要销毁一个对象,可以 代码: String a = “ksadjflasdf“; /do something. / a=null; 这不是销毁一个对象 仅仅是把对一个对象的引用去掉了在 java 中一个对象可以被多个对象引用的只有一个对象不在被引用时才可以被垃圾收集)-XX:SoftRefLRUPolicyMSPerMB=N 这个参数比较有用的,官方解释是:Soft reference 在虚拟机中比在客户集中存活的更长一些。其清除频率可以用命令行参数 -XX:SoftRefLRUPolicyMSPerMB=来控制,这可以指定每兆堆空闲空间的 soft referen

14、ce 保持存活(一旦它不强可达了)的毫秒数,这意味着每兆堆中的空闲空间中的 soft reference 会(在最后一个强引用被回收之后)存活 1 秒钟。注意,这是一个近似的值,因为 soft reference 只会在垃圾回收时才会被清除,而垃圾回收并不总在发生。系统默认为一秒,我觉得没必要等 1 秒,客户集中不用就立刻清除,改为-XX:SoftRefLRUPolicyMSPerMB=0;-Xss 15120 这使得 JBoss 每增加一个线程(thread)就会立即消耗 15M 内存,而最佳值应该是 128K,默认值好像是 512k. +XX:AggressiveHeap 会使得 Xms

15、没有意义。这个参数让 jvm 忽略 Xmx 参数,疯狂地吃完一个 G 物理内存,再吃尽一个 G 的 swap。-Xss:每个线程的 Stack 大小 显示日志参数-verbose:gc 在虚拟机发生内存回收时在输出设备显示信息,格式如下:Full GC 268K-168K(1984K), 0.0187390 secs该参数用来监视虚拟机内存回收的情况。-XX:+PrintGCDetails -XX:+PrintGCTimeStamps(GC 发生的时间) -XX:+PrintGCApplicationStoppedTime(GC 消耗了多少时间) -XX:+PrintGCApplication

16、ConcurrentTime(GC 之间运行了多少时间)-XX:+PrintTenuringDistribution 参数观察各个 Age 的对象总大小2 GC 日志打印GC 调优是个很实验很伽利略的活儿,GC 日志是先决的数据参考和最终验证:-XX:+PrintGCDetails -XX:+PrintGCTimeStamps(GC 发生的时间) -XX:+PrintGCApplicationStoppedTime(GC 消耗了多少时间) -XX:+PrintGCApplicationConcurrentTime(GC 之间运行了多少时间)关于 GC 的显示信息说明:GC 189819K-71

17、72K(1025024K), 0.0343036 secs表示:GC 前占用的内存:189819K K GC 清理后占用的内存:7172K K 总内存:1025024K 0.0343036 secs:jvm 暂停处理的时间3 收集器选择CMS 收集器(并发回收):暂停时间优先配置参数:-XX:+UseConcMarkSweepGC已默认无需配置的参数:-XX:+UseParNewGC(Parallel 收集新生代) -XX:+CMSPermGenSweepingEnabled(CMS 收集持久代) -XX:UseCMSCompactAtFullCollection(full gc 时压缩年老代

18、)初始效果:1g 堆内存的新生代约 60m,minor gc 约 5-20 毫秒,full gc 约 130 毫秒。Parallel 收集器(并行回收):吞吐量优先配置参数: -XX:+UseParallelGC -XX:+UseParallelOldGC(Parallel 收集年老代,从 JDK6.0 开始支持)已默认无需配置的参数: -XX:+UseAdaptiveSizePolicy(动态调整新生代大小)初始效果:1g 堆内存的新生代约 90-110m(动态调整),minor gc 约 5-20 毫秒,full gc 有无UseParallelOldGC 参数分别为 1.3/1.1 秒,

19、差别不大。另外-XX:MaxGCPauseMillis=100 设置 minor gc 的期望最大时间,JVM 会以此来调整新生代的大小,但在此测试环境中对象死的太快,此参数作用不大。4 调优实战Parallel 收集高达 1 秒的暂停时间基本不可忍受,所以选择 CMS 收集器。 在被压测的 Mule 2.0 应用里,每秒都有大约 400M 的海量短命对象产生:因为默认 60M 的新生代太小了,频繁发生 minor gc,大约 0.2 秒就进行一次。因为 CMS 收集器中 MaxTenuringThreshold(新生代对象撑过过多少次 minor gc 才进入年老代的设置)默认0,存活的临时

20、对象不经过 Survivor 区直接进入年老代,不久就占满年老代发生 full gc。对这两个参数的调优,既要改善上面两种情况,又要避免新生代过大,复制次数过多造成 minor gc的暂停时间过长。使用-Xmn 调到 1/3 总内存。观察后设置-Xmn500M,新生代实际约 460m。(用-XX:NewRatio 设置无效,只能用 -Xmn)。添加-XX:+PrintTenuringDistribution 参数观察各个 Age 的对象总大小,观察后设置-XX:MaxTenuringThreshold=5。优化后,大约 1.1 秒才发生一次 minor gc,且速度依然保持在 15-20ms

21、之间。同时年老代的增长速度大大减缓,很久才发生一次 full gc,参数定稿:-server -Xms1536m -Xmx1536m -Xmn512m -XX:+UseConcMarkSweepGC -XX:MaxTenuringThreshold=5 -XX:+ExplicitGCInvokesConcurrent -XX:GCTimeRatio=19 -XX:CMSInitiatingOccupancyFraction=70 -XX:CMSFullGCsBeforeCompaction=0 -Xnoclassg最后服务处理速度从 1180 tps 上升到 1380 tps,调整两个参数提升

22、 17%的性能还是笔很划算的买卖。另外,JDK6 Update 7 自带了一个 VisualVM 工具,内里就是之前也有用过的 Netbean Profiler,类似 JConsole 一样使用,可以看到线程状态,内存中对象以及方法的 CPU 时间等调优重要参考依据。免费捆绑啊,Sun 这样搞法,其他做 Profiler 的公司要关门了。标准参数设置参考样本(tomcat 可用 8G 内存案例)set JAVA_OPTS=%JAVA_OPTS% -server Xms8192m Xmx8192m Xmn1890m -verbose:gc -XX:+UseConcMarkSweepGC -XX:MaxTenuringThreshold=5 -XX:+ExplicitGCInvokesConcurrent -XX:GCTimeRatio=19 -XX:CMSInitiatingOccupancyFraction=70 -XX:CMSFullGCsBeforeCompaction=0 Xnoclassgc -XX:SoftRefLRUPolicyMSPerMB=0

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 生活休闲 > 社会民生

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报