天天看點

減少上下文切換實戰

本節将通過減少線上大量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)