JVM调优整理

JVM 收集器

  1. 默认使用串行收集器, 单个cpu时适用

  2. 吞吐收集器(throughput collector):命令行参数:-XX:+UseParallelGC。在新生代使用并行清除收集策略,在旧生代和默认收集器相同。
    适用:a、拥有2个以上cpu, b、临时对象较多的程序
    -XX:ParallelGCThreads 并行收集线程数量,最好和cpu数量相当

  3. 并发收集器(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))
  • 参考参数:
xmsxmnsurvivorxmngc
6G6G42GCMSInitiatingOccupancyFraction=70
6G6G31.75GCMSInitiatingOccupancyFraction=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
  • 查看gc
root:/# jstat -gcutil 1 1000 5
  S0     S1     E      O      M     CCS    YGC     YGCT    FGC    FGCT     GCT
  0.00  18.57  22.58  42.71  93.54  90.85  22329  318.467     8    2.910  321.377
  0.00  18.57  41.78  42.71  93.54  90.85  22329  318.467     8    2.910  321.377
  0.00  18.57  62.83  42.71  93.54  90.85  22329  318.467     8    2.910  321.377
  • 查看tcp连接数量
root:/# netstat -nat | awk '{print $6}' | sort | uniq -c | sort -n
      1 Foreign
      1 LISTEN
      1 established)
      2 CLOSE_WAIT
     16 TIME_WAIT
     88 ESTABLISHED
  • 找到的线程ID转换为16进制格式
[root@localhost ~]# printf "%x\n" 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)
  • 分析线程的堆栈信息
jstack 6515 > task.info
grep java.lang.Thread.State task.info |awk '{print $2$3$4$5}' |sort| uniq -c
  • 执行jmap把当前的堆dump下来
jmap -dump:live,format=b,file=dump.hprof 6515
  • 将dump.hprof文件使用VisualVM来打开
C:\Users\Administrator>jvisualvm

The launcher has determined that the parent process has a console and will reuse it for its own console output.
Closing the console will result in termination of the running program.
Use '--console suppress' to suppress console output.
Use '--console new' to create a separate console window.

在这里插入图片描述

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

其它方法

  • 查看CPU信息 cat /proc/cpuinfo
  • 查看内存信息 cat /proc/meminfo
  • 查看Java线程数 ps -eLf | grep java -c
  • 查看linux系统里打开文件描述符的最大值 ulimit -u
  • 找到日志里TOP10的异常:grep ‘Exception’ /home/admin/logs/XX.log |awk -F':|,’ ‘{print $2}’|sort |uniq -c |sort -nr|head -10,找到之后可以再用-A 2 -B 2,看定位出日志的前面2行和后面两行。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值