工具
使用Lmbench3[1]可以测量上下文切换的时长。
使用vmstat可以测量上下文切换的次数。
下面是利用vmstat测量上下文切换次数的示例。
$ vmstat 1 procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
0 0 0 127876 398928 2297092 0 0 0 4 2 2 0 0 99 0 0
0 0 0 127868 398928 2297092 0 0 0 0 595 1171 0 1 99 0 0
0 0 0 127868 398928 2297092 0 0 0 0 590 1180 1 0 100 0 0
0 0 0 127868 398928 2297092 0 0 0 0 567 1135 0 1 99 0 0
CS(Content Switch)表示上下文切换的次数,从上面的测试结果中我们可以看到,上下文每1秒切换1000多次。
1.jstack命令dump线程信息
jstack 35031 > dump31
2.统计线程状态
grep java.lang.Thread.State dump31 | 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)
3.打开dump文件查看WAITING(onobjectmonitor)发现是jboss线程,接收任务太少,大量线程闲着waitting
4.配置jboss使用较少线程
5.重新统计发现waitting少了,waitting线程少了,上下文切换就少,因为每一次从 WAITTING到RUNNABLE都会进行一次上下文的切换。可以使用vmstat命令验证一下
dump线程查看出现问题的线程 java.lang.Thread.State: BLOCKED
避免一个线程同时获取多个锁。
避免一个线程在锁内同时占用多个资源,尽量保证每个锁只占用一个资源。
尝试使用定时锁,使用lock.tryLock(timeout)来替代使用内部锁机制。
对于数据库锁,加锁和解锁必须在一个数据库连接里,否则会出现解锁失败的情况。
原文:https://www.cnblogs.com/wod-Y/p/14815385.html