天天看点

减少上下文切换实战

本节将通过减少线上大量WAITING的线程,来减少上下文切换次数。

第一步:用jstack命令dump线程信息,看看pid为3117的进程里的线程都在做什么。

sudo -u admin /opt/ifeve/java/bin/jstack 31177 > /home/tengfei.fangtf/dump17

第二步:统计所有线程分别处于什么状态,发现300多个线程处于WAITING(onobject-monitor)状态。

[tengfei.fangtf@ifeve ~]$ grep java.lang.Thread.State dump17 | awk ‘{print $2$3$4$5}’

| sort | uniq -c

39 RUNNABLE

21 TIMED_WAITING(onobjectmonitor)

6 TIMED_WAITING(parking)

51 TIMED_WAITING(sleeping)

305 WAITING(onobjectmonitor)

3 WAITING(parking)

第三步:打开dump文件查看处于WAITING(onobjectmonitor)的线程在做什么。发现这些线程基本全是JBOSS的工作线程,在await。说明JBOSS线程池里线程接收到的任务太少,大量线程都闲着。

“http-0.0.0.0-7001-97” daemon prio=10 tid=0x000000004f6a8000 nid=0x555e in

Object.wait() [0x0000000052423000]

java.lang.Thread.State: WAITING (on object monitor)

at java.lang.Object.wait(Native Method)

  • waiting on <0x00000007969b2280> (a org.apache.tomcat.util.net.AprEndpointWorker.await(AprEndpoint.java:1464)
  • locked <0x00000007969b2280> (a org.apache.tomcat.util.net.AprEndpointWorker.run(AprEndpoint.java:1489)

    at java.lang.Thread.run(Thread.java:662)

第四步:减少JBOSS的工作线程数,找到JBOSS的线程池配置信息,将maxThreads降到100。

<maxThreads=“250” maxHttpHeaderSize=“8192”

emptySessionPath=“false” minSpareThreads=“40” maxSpareThreads=“75”

maxPostSize=“512000” protocol=“HTTP/1.1”

enableLookups=“false” redirectPort=“8443” acceptCount=“200” bufferSize=“16384”

connectionTimeout=“15000” disableUploadTimeout=“false” useBodyEncodingForURI= “true”>

第五步:重启JBOSS,再dump线程信息,然后统计WAITING(onobjectmonitor)的线程,发现减少了175个。WAITING的线程少了,系统上下文切换的次数就会少,因为每一次从WAITTING到RUNNABLE都会进行一次上下文的切换。读者也可以使用vmstat命令测试一下。

[tengfei.fangtf@ifeve ~]$ grep java.lang.Thread.State dump17 | awk ‘{print $2$3$4$5}’

| sort | uniq -c

44 RUNNABLE

22 TIMED_WAITING(onobjectmonitor)

9 TIMED_WAITING(parking)

36 TIMED_WAITING(sleeping)

130 WAITING(onobjectmonitor)