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=5 os_prio=0 tid=0x00007f83f004b000 nid=0x197b waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"http-nio-9988-AsyncTimeout" #92 daemon prio=5 os_prio=0 tid=0x00007f83f0758000 nid=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=5 os_prio=0 tid=0x00007f83f0382800 nid=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=5 os_prio=0 tid=0x00007f83f11d1000 nid=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=b,file=dump.hprof 6515
将dump.hprof文件使用VisualVM来打开
SpringBoot TOMCAT调优
tomcat参数说明
maxThreads 客户请求最大线程数
minSpareThreads Tomcat初始化时创建的 socket 线程数
maxSpareThreads Tomcat连接器的最大空闲 socket 线程数
enableLookups 若设为true, 则支持域名解析,可把 ip 地址解析为主机名
redirectPort 在需要基于安全通道的场合,把客户请求转发到基于SSL 的 redirectPort 端口
acceptAccount 监听端口队列最大数,满了之后客户请求会被拒绝(不能小于maxSpareThreads )
connectionTimeout 连接超时
minProcessors 服务器创建时的最小处理线程数
maxProcessors 服务器同时最大处理线程数
URIEncoding URL统一编码
tomcat在springboot上的配置ServerProperties.java --> application.properties
server.tomcat.accesslog.enabled =
server.tomcat.accesslog.pattern =
server.tomcat.accesslog.directory =
server.tomcat.accesslog.prefix =
server.tomcat.accesslog.suffix =
server.tomcat.accesslog.rotate =
server.tomcat.accesslog.renameOnRotate =
server.tomcat.accesslog.requestAttributesEnabled=
server.tomcat.accesslog.buffered =
server.tomcat.internalProxies =
server.tomcat.protocolHeader =
server.tomcat.protocolHeaderHttpsValue =
server.tomcat.portHeader =
server.tomcat.remoteIpHeader=
server.tomcat.basedir =
server.tomcat.backgroundProcessorDelay =
server.tomcat.maxThreads =
server.tomcat.minSpareThreads =
server.tomcat.maxHttpPostSize =
server.tomcat.maxHttpHeaderSize =
server.tomcat.redirectContextRoot =
server.tomcat.uriEncoding =
server.tomcat.maxConnections =
server.tomcat.acceptCount =
server.tomcat.additionalTldSkipPatterns =
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虚拟机(内存模型+GC算法+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.扩容?先尝试一下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