热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

jvm调优案例

JVM调优JVM收集器默认使用串行收集器,单个cpu时适用吞吐收集器(throughputcollector):命令行参

JVM调优


JVM 收集器

默认使用串行收集器, 单个cpu时适用吞吐收集器(throughput collector):命令行参数:-XX:+UseParallelGC。在新生代使用并行清除收集策略,在旧生代和默认收集器相同。
适用:a、拥有2个以上cpu, b、临时对象较多的程序
-XX:ParallelGCThreads 并行收集线程数量,最好和cpu数量相当并发收集器(concurrent low pause collector):命令行参数:-XX:+UseConcMarkSweepGC。在旧生代使用并发收集策略,大部分收集工作都是和应用并发进行的,在进行收集的时候,应用的暂停时间很短。默认配套打开 -XX:+UseParNewGC,会在新生代使用并行复制收集。
适用:a、拥有多个cpu, b、老对象较多的程序

-XX:+UseCMSCompactAtFullCollection:打开对年老代的压缩。可能会影响性能,但是可以消除碎片
-XX:+UseFastAccessorMethods 原始类型的快速优化
-XX:SurvivorRatio 新生区中,eden&survivor的比例,设置为8
-XX:TargetSurvivorRatio 生存区需要做垃圾回收的比例值,默认为50%,设置高些可以更好的利用该区

设置jvm参数

$ java -jar -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=128m -Xms1024m -Xmx1024m -Xmn256m -Xss256k -XX:SurvivorRatio=8 -XX:+UseConcMarkSweepGC newframe-1.0.0.jar$JAVA_ARGS
.=
"
-Dresin.home=$SERVER_ROOT
-server
-Xmx3000M
-Xms3000M
-Xmn600M
-XX:PermSize=500M
-XX:MaxPermSize=500M
-Xss256K
-XX:+DisableExplicitGC
-XX:SurvivorRatio=1
-XX:+UseConcMarkSweepGC
-XX:+UseParNewGC
-XX:+CMSParallelRemarkEnabled
-XX:+UseCMSCompactAtFullCollection
-XX:CMSFullGCsBeforeCompaction=0
-XX:+CMSClassUnloadingEnabled
-XX:LargePageSizeInBytes=128M
-XX:+UseFastAccessorMethods
-XX:+UseCMSInitiatingOccupancyOnly
-XX:CMSInitiatingOccupancyFraction=70
-XX:SoftRefLRUPolicyMSPerMB=0
-XX:+PrintClassHistogram
-XX:+PrintGCDetails
-XX:+PrintGCTimeStamps
-XX:+PrintHeapAtGC
-Xloggc:log/gc.log
";

调优策略

JVM各个参数之间有一个平衡性的,另外根据业务类型和实际的运行环境都有不一样的效果。但是有些约定俗成的规定还是值得借鉴的:
1)堆内存不超过物理内存的3/4
2)年轻代的大小不超过堆内存的3/8
3)CMSInitiatingOccupancyFraction一般不低于70%

(Xmx-Xmn)*(1-CMSInitiatingOccupancyFraction/100)>=(Xmn-Xmn/(SurvivorRatior+2))

参考参数:

xms

xmn

survivor

xmn

gc

6G

6G

4

2G

CMSInitiatingOccupancyFraction=70

6G

6G

3

1.75G

CMSInitiatingOccupancyFraction=70


工具使用

查看线程cpu占用1

[root@localhost ~]# ps p 6515 -L -o pcpu,pid,tid,time,tname,cmd --sort pcpu
%CPU PID TID TIME TTY CMD 0.0 6515 6515 00:00:00 pts/1 java -jar xxl-job-admin-2.0.2-SNAPSHOT.jar 0.0 6515 6523 00:00:04 pts/1 java -jar xxl-job-admin-2.0.2-SNAPSHOT.jar 0.0 6515 6529 00:00:00 pts/1 java -jar xxl-job-admin-2.0.2-SNAPSHOT.jar

查看线程cpu占用2

[root@localhost ~]# ps -mp 6515 -o THREAD,tid,time
USER %CPU PRI SCNT WCHAN USER SYSTEM TID TIME
root 0.3 - - - - - - 00:00:58
root 0.0 19 - futex_ - - 6515 00:00:00
root 0.0 19 - futex_ - - 6523 00:00:04
root 0.0 19 - futex_ - - 6529 00:00:00
root 0.0 19 - futex_ - - 6530 00:00:00

找到的线程ID转换为16进制格式

[root@localhost ~]# printf "%x
" 6523
197b

打印线程的堆栈信息

[root@localhost ~]# jstack 6515 | grep 197b -A 30
"DestroyJavaVM" #94 prio&#61;5 os_prio&#61;0 tid&#61;0x00007f83f004b000 nid&#61;0x197b waiting on condition [0x0000000000000000] java.lang.Thread.State: RUNNABLE"http-nio-9988-AsyncTimeout" #92 daemon prio&#61;5 os_prio&#61;0 tid&#61;0x00007f83f0758000 nid&#61;0x19e4 waiting on condition [0x00007f8352bee000] java.lang.Thread.State: TIMED_WAITING (sleeping) at java.lang.Thread.sleep(Native Method) at org.apache.coyote.AbstractProtocol$AsyncTimeout.run(AbstractProtocol.java:1149) at java.lang.Thread.run(Thread.java:748)"http-nio-9988-Acceptor-0" #91 daemon prio&#61;5 os_prio&#61;0 tid&#61;0x00007f83f0382800 nid&#61;0x19e3 runnable [0x00007f8352cef000] java.lang.Thread.State: RUNNABLE at sun.nio.ch.ServerSocketChannelImpl.accept0(Native Method) at sun.nio.ch.ServerSocketChannelImpl.accept(ServerSocketChannelImpl.java:422) at sun.nio.ch.ServerSocketChannelImpl.accept(ServerSocketChannelImpl.java:250) - locked <0x00000006c7c2ada0> (a java.lang.Object) at org.apache.tomcat.util.net.NioEndpoint$Acceptor.run(NioEndpoint.java:482) at java.lang.Thread.run(Thread.java:748)"http-nio-9988-ClientPoller-1" #90 daemon prio&#61;5 os_prio&#61;0 tid&#61;0x00007f83f11d1000 nid&#61;0x19e2 runnable [0x00007f8352df0000] java.lang.Thread.State: RUNNABLE at sun.nio.ch.EPollArrayWrapper.epollWait(Native Method) at sun.nio.ch.EPollArrayWrapper.poll(EPollArrayWrapper.java:269) at sun.nio.ch.EPollSelectorImpl.doSelect(EPollSelectorImpl.java:93) at sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:86) - locked <0x00000006c7c2b548> (a sun.nio.ch.Util$3) - locked <0x00000006c7c2b538> (a java.util.Collections$UnmodifiableSet) - locked <0x00000006c7c2b400> (a sun.nio.ch.EPollSelectorImpl) at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:97) at org.apache.tomcat.util.net.NioEndpoint$Poller.run(NioEndpoint.java:825) at java.lang.Thread.run(Thread.java:748)

执行jmap把当前的堆dump下来

jmap -dump:live,format&#61;b,file&#61;dump.hprof 6515

将dump.hprof文件使用VisualVM来打开


SpringBoot TOMCAT调优

tomcat参数说明

maxThreads 客户请求最大线程数
minSpareThreads Tomcat初始化时创建的 socket 线程数
maxSpareThreads Tomcat连接器的最大空闲 socket 线程数
enableLookups 若设为true, 则支持域名解析&#xff0c;可把 ip 地址解析为主机名
redirectPort 在需要基于安全通道的场合&#xff0c;把客户请求转发到基于SSL 的 redirectPort 端口
acceptAccount 监听端口队列最大数&#xff0c;满了之后客户请求会被拒绝&#xff08;不能小于maxSpareThreads &#xff09;
connectionTimeout 连接超时
minProcessors 服务器创建时的最小处理线程数
maxProcessors 服务器同时最大处理线程数
URIEncoding URL统一编码

tomcat在springboot上的配置ServerProperties.java --> application.properties

server.tomcat.accesslog.enabled &#61;
server.tomcat.accesslog.pattern &#61;
server.tomcat.accesslog.directory &#61;
server.tomcat.accesslog.prefix &#61;
server.tomcat.accesslog.suffix &#61;
server.tomcat.accesslog.rotate &#61;
server.tomcat.accesslog.renameOnRotate &#61;
server.tomcat.accesslog.requestAttributesEnabled&#61;
server.tomcat.accesslog.buffered &#61;
server.tomcat.internalProxies &#61;
server.tomcat.protocolHeader &#61;
server.tomcat.protocolHeaderHttpsValue &#61;
server.tomcat.portHeader &#61;
server.tomcat.remoteIpHeader&#61;
server.tomcat.basedir &#61;
server.tomcat.backgroundProcessorDelay &#61;
server.tomcat.maxThreads &#61;
server.tomcat.minSpareThreads &#61;
server.tomcat.maxHttpPostSize &#61;
server.tomcat.maxHttpHeaderSize &#61;
server.tomcat.redirectContextRoot &#61;
server.tomcat.uriEncoding &#61;
server.tomcat.maxConnections &#61;
server.tomcat.acceptCount &#61;
server.tomcat.additionalTldSkipPatterns &#61;

tomcat在application.yml上的配置

server: tomcat: min-spare-threads: 20 max-threads: 100 connection-timeout: 5000

参考:
1.JAVAEE文档:https://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html
2.深入理解JAVA虚拟机(内存模型&#43;GC算法&#43;JVM调优):https://www.cnblogs.com/yueshutong/p/9768298.html
3.JVM调优实践:https://blog.wangqi.love/articles/Java/JVM%E8%B0%83%E4%BC%98%E5%AE%9E%E8%B7%B5.html
4.JVM解读-性能调优实例:https://www.jianshu.com/p/2c4b091deaa3
5.扩容&#xff1f;先尝试一下JVM调优吧:https://sq.163yun.com/blog/article/211688346067283968
6.JVM调优参数简介、调优目标及调优经验https://blog.csdn.net/jisuanjiguoba/article/details/80176223
7.jvm优化必知系列——监控工具https://juejin.im/post/59e6c1f26fb9a0451c397a8c
8.JVM活学活用——优化springboothttps://cloud.tencent.com/developer/article/1089954
9.SpringBoot服务器压测对比(jetty、tomcat、undertow)https://my.oschina.net/shyloveliyi/blog/2980868


推荐阅读
  • Java中高级工程师面试必备:JVM核心知识点全面解析
    对于软件开发人员而言,随着技术框架的不断演进和成熟,许多高级功能已经被高度封装,使得初级开发者只需掌握基本用法即可迅速完成项目。然而,对于中高级工程师而言,深入了解Java虚拟机(JVM)的核心知识点是必不可少的。这不仅有助于优化性能和解决复杂问题,还能在面试中脱颖而出。本文将全面解析JVM的关键概念和技术细节,帮助读者全面提升技术水平。 ... [详细]
  • JVM参数设置与命令行工具详解
    JVM参数配置与命令行工具的深入解析旨在优化系统性能,通过合理设置JVM参数,确保在高吞吐量的前提下,有效减少垃圾回收(GC)的频率,进而降低系统停顿时间,提升服务的稳定性和响应速度。此外,本文还将详细介绍常用的JVM命令行工具,帮助开发者更好地监控和调优JVM运行状态。 ... [详细]
  • 深入理解Spark框架:RDD核心概念与操作详解
    RDD是Spark框架的核心计算模型,全称为弹性分布式数据集(Resilient Distributed Dataset)。本文详细解析了RDD的基本概念、特性及其在Spark中的关键操作,包括创建、转换和行动操作等,帮助读者深入理解Spark的工作原理和优化策略。通过具体示例和代码片段,进一步阐述了如何高效利用RDD进行大数据处理。 ... [详细]
  • 在启用分层编译的情况下,即时编译器(JIT)的触发条件涉及多个因素,包括方法调用频率、代码复杂度和运行时性能数据。本文将详细解析这些条件,并探讨分层编译如何优化JVM的执行效率。 ... [详细]
  • 掌握DSP必备的56个核心问题,我已经将其收藏以备不时之需! ... [详细]
  • Windows环境下详细教程:如何搭建Git服务
    Windows环境下详细教程:如何搭建Git服务 ... [详细]
  • 在Java NIO中,`ByteBuffer` 的内存分配方式分为 `allocate` 和 `allocateDirect`。前者在JVM堆内存中分配空间,返回 `HeapByteBuffer` 实例,初始位置为0,容量和限制由参数指定。而 `allocateDirect` 则在操作系统本地内存中分配,返回 `DirectByteBuffer`,适用于需要频繁与I/O操作交互的场景,性能更高但管理成本较大。两者在内存管理和性能上各有优劣,选择时需根据具体应用场景权衡。 ... [详细]
  • 深入解析Gradle中的Project核心组件
    在Gradle构建系统中,`Project` 是一个核心组件,扮演着至关重要的角色。通过使用 `./gradlew projects` 命令,可以清晰地列出当前项目结构中包含的所有子项目,这有助于开发者更好地理解和管理复杂的多模块项目。此外,`Project` 对象还提供了丰富的配置选项和生命周期管理功能,使得构建过程更加灵活高效。 ... [详细]
  • 深入解析Java中HashCode的功能与应用
    本文深入探讨了Java中HashCode的功能与应用。在Java中,HashCode主要用于提高哈希表(如HashMap、HashSet)的性能,通过快速定位对象存储位置,减少碰撞概率。文章详细解析了HashCode的生成机制及其在集合框架中的作用,帮助开发者更好地理解和优化代码。此外,还介绍了如何自定义HashCode方法以满足特定需求,并讨论了常见的实现误区和最佳实践。 ... [详细]
  • 本文深入探讨了Java枚举类型的使用与实践,详细解析了枚举的基本用法及其在实际开发中的应用。首先介绍了枚举作为常量的替代方案,自JDK 1.5起,通过枚举可以更加简洁、安全地定义常量,避免了传统方式中可能出现的错误。此外,文章还探讨了枚举在实现单例模式、状态机等场景中的优势,并提供了多个实际案例,帮助开发者更好地理解和运用这一强大的语言特性。 ... [详细]
  • 本文将深入探讨Java编程语言中顶级类`Object`的源码实现,旨在为Java新手提供进阶指导。`Object`类是所有Java类的基类,了解其内部机制对于提升编程技能至关重要。文章首先介绍了API文档的使用方法,这对于有开发经验的Java程序员来说是不可或缺的工具。通过详细解析`Object`类的关键方法和属性,读者可以更好地理解Java的核心原理和设计思想。此外,文章还提供了实际代码示例,帮助读者在实践中掌握这些知识。 ... [详细]
  • Apache Maven 3.5.0 版本的发布带来了多项重要特性和性能优化。该版本不仅改进了构建过程的效率,还增强了对复杂项目结构的支持。通过引入新的依赖解析机制和优化的插件系统,Maven 3.5.0 在提升用户体验的同时,也确保了更高的稳定性和兼容性。此外,该版本还修复了多个已知问题,进一步提升了整体的可靠性和安全性。 ... [详细]
  • 如何在微信公众平台集成新浪云服务应用摘要:新浪云服务平台SinaAppEngine(简称SAE)自2009年启动内部研发,并于同年对外开放。本文详细介绍了如何利用SAE的强大功能,在微信公众平台上构建高效、稳定的云服务应用程序,涵盖从环境配置到应用部署的全流程,为开发者提供详尽的技术指导与实践案例。 ... [详细]
  • 在Java中,一个类可以实现多个接口,但是否能够继承多个类则存在限制。本文探讨了Java中实现多继承的方法及其局限性,详细分析了通过接口、抽象类和组合等技术手段来模拟多继承的策略,并讨论了这些方法的优势和潜在问题。 ... [详细]
  • 自1995年问世以来,Java已历经14年的演变,在快速发展的信息技术领域中展现出持续的活力与创新。如今,Java不仅是一种编程语言,更发展成为一个多功能平台、活跃的开发者社区及成熟的技术生态系统。 ... [详细]
author-avatar
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有