Jvm 性能调优

本文深入探讨了JVM调优的几个关键问题,包括解决堆栈溢出、减少STW时间、处理DirectMemory引起的内存溢出等。通过具体案例解析,如调整-Xss参数减少堆栈溢出风险、使用-XX:+CMSParallelInitialMarkEnabled减少初始化标记阶段耗时、-XX:+CMSScavengeBeforeRemark缩短remark阶段停顿时间,以及如何合理配置DirectMemory避免OOM。此外,还提供了一个OA系统性能调优的实际案例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

堆栈溢出(设置栈空间太小,导致栈溢出)
-Xss256k 每个线程堆栈空间太小,导致溢出
-Xss256k这个参数调整了,可能会影响trace的调用。 报如下错误:
Java.lang.StackOverflowError
at net.sf.jsqlparser.util.deparser.ExpressionDeParser.visitBinaryExpression(ExpressionDeParser.java:278)
at net.sf.jsqlparser.util.deparser.ExpressionDeParser.visit(ExpressionDeParser.java:246)
at net.sf.jsqlparser.expression.operators.conditional.OrExpression.accept(OrExpression.java:37)
at net.sf.jsqlparser.util.deparser.ExpressionDeParser.visitBinaryExpression(ExpressionDeParser.java:278)
at net.sf.jsqlparser.util.deparser.ExpressionDeParser.visit(ExpressionDeParser.java:246)
因为这个参数是设置每个线程的堆栈大小。JDK5.0以后每个线程堆栈大小为1M,以前每个线程堆栈大小为256K。在相同物理内存下,减小这个值能生成更多的线程。

问题二:初始化标记阶段耗时过长:
一般的建议是cms阶段两次STW的时间不超过200ms,如果是CMS Initial mark阶段导致的时间过长:
在初始化标记阶段(CMS Initial mark),为了最大限度地减少STW的时间开销,我们可以使用:
-XX:+CMSParallelInitialMarkEnabled
开启初始标记过程中的并行化,进一步提升初始化标记效率;

问题三:remark阶段stw的时间过长
如下图:

可以采用的方式是:
在CMS GC前启动一次ygc,目的在于减少old gen(老年代)对ygc gen(年轻代)的引用,降低remark时的开销—–一般CMS的GC耗时 80%都在remark阶段
-XX:+CMSScavengeBeforeRemark

问题四:

nio框架占用DirectMemory导致的OutOfMemoryError
处理方式:使用XX:+DisableExplicitGC
增加DirectMemory的大小;
1、DirectMemory不属于java堆内存、分配内存其实是调用操作系统的Os:malloc()函数。
2、容量可通过-XX:MaxDirectMemorySize指定,如果不指定,则默认与Java堆的最大值(-Xmx指定)一样。注意 ibm jvm默认Direct Memory与-Xmx无直接关系。
3、Direct Memory 内存的使用避免Java堆和Native堆中来回复制数据。从某些场景中提高性能。
4、直接ByteBuffer对象会自动清理本机缓冲区,但这个过程只能作为Java堆GC的一部分来执行,因此它们不会自动响应施加在本机堆上的压力。
5、GC仅在Java堆被填满,以至于无法为堆分配请求提供服务时发生,或者在Java应用程序中显示调用System.gc()函数来释放内存(一些NIO框架就是用这个方法释放占用的DirectMemory)。
6、该区域使用不合理,也是会引起OutOfMemoryError。
7、在需要频繁创建Buffer的场合,由于创建和销毁DirectBuffer的代价比较高昂,是不宜使用DirectBuffer的,但是如果能将DirectBuffer进行复用,那么 ,在读写频繁的情况下,它完全可以大幅改善性能。(对DirectBuffer的读写比普通Buffer快,但是对他的创建和销毁比普通Buffer慢)。

项目中性能调优案例:

oa 系统 针对员工考核 生成一个excel表格,表格里面包含很多的信息,可以理解为大对象,用户请求生成,下载,并且保存一份在redis里面。

问题:访问卡顿
排查过程:优化sql(建索引) 监控cpu 内存(top命令)
访问系统功能很慢,而且时间不固定,通过排查ps jstat full gc 时间很长很长,那就是说明垃圾回收经常发生,系统内存称爆了

大对象放到老年代中,导致老年代内存不够,触发full gc ,触发full gc 会stop the world 而设置jvm 堆内存60g,回收过程很大。

解决方案:

nginx 负载均衡

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值