前段时间在公司进行了GC的调优实践,记录一下供以后参考。基本上,和网上其他人提供的配置都差不多。
调优前情况:
采用并行收集器,系统TPS约600,为每隔15分钟左右会产生一次FullGC,FullGC的时间大约15秒,FullGC期间系统无法接收任何响应,操作系统的CPU使用率下降到5%一下(平时大约30%-40%)。
调整前JVM参数:
-server -D_Offline_FileDataArchive=true -Xms512m -Xmx2048m -Xss256k -XX:MaxPermSize=256m -XX:+UseParallelGC -XX:+UseParallelOldGC -XX:ParallelGCThreads=4 -XX:SurvivorRatio=16
调试过程:
1. 添加JVM参数,打开GC的log,发现-Xms设置为512m是比较合适的。
JVM参数:
-Xloggc:traf_gc.log -verbose:gc -XX:+PrintGCDetails -XX:+PrintHeapAtGC -XX:+PrintGCTimeStamps
2.采用并发收集器,替代并行收集器,继续设置-Xms为512m
JVM参数:
-XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:+CMSPermGenSweepingEnabled -XX:+CMSClassUnloadingEnabled -Xnoclassgc
3. 发现时不时会在Old代GC时,系统会停止操作,无法接收任何响应,就像采用并行收集器的FullGC现象,gc的日志里显示“promotion failed”。原来是Old代在进行GC时,GC的收集速度小于Old的增加速度,导致系统彻底暂停下来,进行FullGC。
JVM参数:
-XX:CMSInitiatingOccupancyFraction=80
4. 发现PermGen的增长特别快,而且GC后,PermGen还在缓慢增加,最终导致PermGen爆满,系统停止运行。究其原因,是因为添加了-Xnoclassgc。 这个-Xnoclassgc是表示不多class进行垃圾回收,原本考虑class一旦load起来了,是很少会被回收的,但这只是自己毫无根据的假设。实际上,因为我们的代码里用到了Spring,hibernate,这些框架用到了很多反射,产生了大量临时的class,所以系统需要对class进行垃圾回收,-Xnoclassgc是绝不能打开的。
JVM参数:
-Xnoclassgc
调整后情况:
系统运行了3天,没有出现停机FullGC的现象,TPS提高倒不多大概到650左右。
调整后JVM参数:
-server -D_Offline_FileDataArchive=true -Xms2048m -Xmx2048m -Xmn512m
-Xss256k -XX:MaxPermSize=256m -XX:+UseParNewGC -XX:+UseConcMarkSweepGC
-XX:+CMSPermGenSweepingEnabled -XX:+CMSClassUnloadingEnabled
-XX:SurvivorRatio=6 -XX:MaxTenuringThreshold=7
-XX:CMSInitiatingOccupancyFraction=80
-XX:+UseCMSCompactAtFullCollection -XX:CMSFullGCsBeforeCompaction=0
-XX:SoftRefLRUPolicyMSPerMB=0
关于GC分代垃圾回收过程的演示,JavaEve上找到一个很好的文章
http://chenchendefeng.iteye.com/blog/455883
分享到:
相关推荐
增量式GC的具体实现算法是Train GC算法,它通过动态调整对象的分组,使得GC可以优先处理那些较旧且较少访问的对象,从而提高回收效率并减少程序暂停时间。 #### 四、分代收集 **4.1 分代理论背景** 分代收集...
2. **并行GC(Parallel GC)**:也称为吞吐量优先GC,它在多线程环境中运行,提高了GC效率,减少了整体运行时间,但STW仍然存在。 3. **并发标记GC(Concurrent Mark Sweep, CMS)**:CMS旨在减少STW的时间,它将大...
2. **Parallel GC**:也称为吞吐量优先GC,它在多线程环境下提高垃圾收集效率,以最大化应用程序的运行时间。它使用多个线程同时处理年轻代和老年代的垃圾收集。 3. **CMS GC**:并发标记扫描GC,主要用于服务器...
4. **GC性能调优**:如何通过调整JVM参数来优化垃圾收集的性能,减少停顿时间,提高应用程序响应速度。 5. **内存泄漏与内存溢出**:理解这两个问题的原因和解决方法,以及如何通过分析工具检测它们。 6. **垃圾...
2. 响应时间优先:强调快速响应用户请求,即使牺牲一定的吞吐量,也需确保系统延迟最小,适合交互式应用。 在实际操作中,JVM调优涉及参数调整,如堆内存大小(`-Xms`和`-Xmx`)、新生代与老年代的比例(`-XX:...
这对于对响应时间要求较高的应用,如实时系统或在线游戏,尤其有利。Sun JDK的HotSpot JVM提供对增量式GC的支持,可以通过`-Xincgc`参数启用。HotSpot JVM的实现采用了Train GC算法,通过对象分组和分层,优先回收最...
- CMS/G1参数调整:例如设置并发比、初始暂停时间目标等,平衡响应速度与吞吐量。 4. **性能监控与诊断工具** - JVisualVM:官方提供的全功能JVM监控工具,包括内存、线程、类加载、CPU等监控。 - JConsole:另...
CMS(Concurrent Mark Sweep)收集器追求的是低暂停时间,适合对响应时间敏感的应用。其配置参数如-XX:+UseConcMarkSweepGC可以启用CMS,而-XX:+UseParNewGC则用于新生代的并行收集。CMS还包含-XX:+...
- **应用程序响应时间延长**:用户请求处理延迟增加。 - **频繁的GC事件**:GC日志显示频繁的full GC或年轻代GC。 - **内存使用率持续升高**:监控工具显示内存使用率不断上升且无法释放。 这些问题的根源可能在于...
- **并发收集器(响应时间优先)**:如CMS(Concurrent Mark Sweep),适用于需要低延迟的应用,如`-XX:+UseConcMarkSweepGC`。CMS主要处理年老代,减少Full GC的暂停时间。 5. **CMS收集器**: - CMS收集器使用...
- 垃圾回收器选择:根据不同的应用场景选择合适的垃圾回收器,例如响应时间优先的并发收集器适用于对应用响应时间有较高要求的场景。 综上所述,高性能应用的设计与开发涉及到多个层面的知识和技术。通过对上述...
2. **选择合适的垃圾收集器**:考虑系统资源和应用特点,如响应时间优先或吞吐量优先。 3. **监控和分析GC日志**:通过`-XX:+PrintGCDetails`等选项输出GC日志,分析垃圾回收行为。 4. **减少Full GC**:优化对象...
每种GC有其优缺点,如Serial适合单线程环境,Parallel提升并行度,CMS适用于响应时间优先,G1则力求平衡暂停时间和吞吐量。选择合适的垃圾收集器并调整其参数是调优的关键。 3. **新生代与老年代比例**:-XX:...
通过分析和调整JVM的各种设置,包括线程池大小、GC日志配置、类加载策略等,可以改善系统响应时间、减少内存消耗、避免Full GC等问题,从而提高整体应用性能。 《深入JAVA虚拟机》这本书的随书源代码可能包含了各种...
- **常用算法**:排序(快速排序、归并排序、冒泡排序等)、查找(二分查找、哈希查找等)、图遍历(深度优先、广度优先)。 3. **并发编程**: - **线程安全**:理解 volatile、synchronized 关键字的作用。 - ...
- 图论:深度优先搜索(DFS)、广度优先搜索(BFS)的应用。 - 链表操作:头插法、尾插法、反转链表等。 6. **框架知识** - Spring Boot:快速开发框架,自动配置、启动器、Spring MVC、AOP的理解。 - MyBatis...
- **使用G1、ZGC等新型GC**:降低停顿时间,提高应用响应速度。 - **代码优化**:避免创建大量短生命周期对象,合理使用对象池,减少对象间的引用关系。 ### 7. 类加载与反射 反射允许在运行时动态加载、实例化类,...
- **CMS收集器**:注重缩短暂停时间,适用于对响应时间要求较高的场景。 - **G1收集器**:面向服务端应用,目标是最小化停顿时间并具有高度可预测性。 ### 四、性能调优 #### 4.1 监控工具 为了更好地理解和优化...
- 避免使用函数表达式(例如`functionName = function() {...}`),优先使用函数声明(`function functionName() {...}`)。 - 使用箭头函数(`=>`)来简化一元或二元函数的语法。 - 避免副作用和隐式全局变量。 ...