2.上下文切换

概念:

CPU过时间片分配算法来循环执行任,当前任务执一个时间片后会切到下一个任。但是,在切前会保存上一个任的状,以便下次切个任务时,可以再加载这个任的状。所以任从保存到再加程就是一次上下文切

测试上下文切次数和时长
  1. 使用Lmbench3[1]可以量上下文切时长
  2.  使用vmstat可以量上下文切的次数。
下面是利用vmstat量上下文切次数的示例
 

CSContent Switch)表示上下文切的次数,从上面的测试结果中我可以看到,上下文每1秒切1000多次。

 
 如何减少上下文切
 
  1. 线锁时,会引起上下文切,所以多线理数据,可以用一些法来避免使用,如将数据的ID按照Hash算法取模分段,不同的线理不同段的数据。 
  2. CAS算法。JavaAtomic包使用CAS算法来更新数据,而不需要加。 
  3. 避免建不需要的线程,比如任很少,但是建了很多线程来理,这样会造成大量线程都于等待状
  4. 程:在单线程里实现多任度,并在单线程里持多个任务间的切
     

 
 减少上下文切换实战
 
 第一步:jstack命令dump出pid3117程里的线程信息
 
sudo -u admin /opt/ifeve/java/bin/jstack 31177 > /home/tengfei.fangtf/dump17 
 
 第二步:统计所有线程分别处于什么状发现300多个线WAITINGonobjectmonitor)状
[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文件WAITINGonobjectmonitor)的线程在做什么。发现这线程基本全是JBOSS的工作线程,在awaitJBOSS线程池里线程接收到的任太少,大量线程都着。 


 第四步:减少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线程信息,然后统计WAITINGonobjectmonitor)的线程,发现减少了175个。WAITING线程少了,系上下文切的次数就会少,因每一次从WAITTINGRUNNABLE都会行一次上下文的切者也可以使用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)
  1 WAITING(parking) 
 
 
 

posted on 2017-02-20 15:47  近博  阅读(506)  评论(0编辑  收藏  举报

导航