性能监控/优化系列——内存/线程/锁相关

 1. 内存的分页(paging)、交换(swapping)、锁和线程的上下文切换(分为voluntary and involuntary context switching)需要监控。两种上下文的区别:voluntary ——voluntarily takes itself off the CPU;involuntary ——占用时间期满或优先级更高的线程取代。

2. 如果一个java程序或JVM在发生内存交换(swapping)表明有性能问题需要关注。
3. 当发现JVM的垃圾回收时间很长时,很可能是内存不足发生swapping。如果JVM运行在内存不足的机器上,它的内存堆可能会被交换出去,当做垃圾回收的时候需要遍历整个堆的内存,所以会要求处在磁盘中的数据给交换到内存,这个时候会产生很大的延迟,导致很多线程会停止运行。(一般情况下,当内存不够时,OS内核page scanner会去扫描内存,将那些不再使用的内存提供给需要的应用程序,如果不能找到足够的内存就会把最近最少被使用的内存page交换到磁盘。可获得的内存越少page scan rate就越高。
4. 从上面几点可以看出:当page scanner扫描的次数(Solaris下可以用vmstat,对应的列为‘sr)不为0(增多)且free内存有下降的趋势,那么交换swapping就会发生,性能就会开始下降。
Solaris下vmstat命令
kthr memory page disk faults cpu
r b w swap free re mf pi po fr de sr cd f0 s0 -- in sy cs us sy id
1 0 0 499792 154720 1 1697 0 0 0 0 0 0 0 0 12 811 612 1761 90 7 4
1 0 0 498856 44052 1 3214 0 0 0 0 0 0 0 0 12 1290 2185 3078 66 18 15
3 0 0 501188 17212 1 1400 2 2092 4911 0 37694 0 53 0 12 5262 3387 1485 52 27 21
1 0 0 500696 20344 26 2562 13 4265 7553 0 9220 0 66 0 12 1192 3007 2733 71 17 12
1 0 0 499976 20108 3 3146 24 3032 10009 0 10971 0 63 0 6 1346 1317 3358 78 15 7
1 0 0 743664 25908 61 1706 70 8882 10017 0 19866 0 78 0 52 1213 595 688 70 12 18
5. 关于锁,Java5之前的锁机制是直接代理了OS的锁元素( delegate Java monitor operations directly  to operating system monitors, or mutex primitives),这样会提高 system CPU utilization,因为 system mutex primitives涉及到系统调用 ,也由于直接代理的因素需要OS级别的命令就可以查看到Java应用的锁竞争状况。但是,Java5之后有了变化,不再直接依赖OS的锁机制,而是在用户代码级别实现了锁逻辑,因此监控方法发生了变化。Java5的锁实现如下: spin in a tight loop trying to acquire a lock,  if not successful after a number of tight loop spins, park the thread and wait to be  notified when to try acquiring the lock again,也就是说,在一个循环中去获取锁,如果几次没有成功,那么就停止( parking )线程进行等待,直到被通知为止。
6. Java的锁竞争引起了线程上下文切换,CPU利用率很高,反过来讲,如果发现上下文切换过高,那么很可能是锁竞争导致的。The act of parking a thread along with awaking a thread results in an operating system voluntary context switch,从CPU时钟周期基本来讲,这是一个代价很高的操作,每个上下文交换需要80000以上个clock cycle。一般经验值:experiencing 5% or more of its available clock cycles in voluntary context switches(这个可以以1s时间周期为计算)很可能存在锁竞争。事实上,当该值达到3% to 5%就应该进行相关的排查工作。
7. 上述百分比的计算方法:如果一台机器的主频为3g,也就是30亿个时钟周期每秒,那么计算公式如下:Solaris——1s内上下文切换数*80000/30亿;Linux——1s内上下文切换数/虚拟处理器数*80000/30亿(为什么要除以虚拟处理器数:因为pidstat -w所统计的是所有处理的上下文切换数,每个处理器(核)都有自己的时钟,而Solaris中统计是平均每个核的上下文切换数,所以不需要在做除法)。
Solaris下mpstat命令
$ mpstat 5
CPU minf mjf xcal intr ithr csw icsw migr smtx srw syscl usr sys wt idl
0 4 0 1 479 357 8201 87 658 304 0 6376 86 4 0 10
1 3 0 1 107 3 8258 97 768 294 0 5526 85 4 0 10
CPU minf mjf xcal intr ithr csw icsw migr smtx srw syscl usr sys wt idl
0 0 0 0 551 379 8179 91 717 284 0 6225 85 5 0 10
1 2 0 0 2292 2 8247 120 715 428 0 7062 84 5 0 10
CPU minf mjf xcal intr ithr csw icsw migr smtx srw syscl usr sys wt idl
0 0 0 0 562 377 8007 98 700 276 0 6493 85 5 0 10
1 0 0 0 2550 4 8133 137 689 417 0 6627 86 4 0 11
CPU minf mjf xcal intr ithr csw icsw migr smtx srw syscl usr sys wt idl
0 0 0 0 544 378 7931 90 707 258 0 6609 87 5 0 8
1 0 0 0 2428 1 8061 125 704 409 0 6045 88 3 0 9
Linux下pidstat命令
$ pidstat -w -I -p 9391 5
Linux 2.6.24-server (payton) 07/10/2008
08:57:19 AM PID cswch/s nvcswch/s Command
08:57:26 AM 9391 3645 322 java
08:57:31 AM 9391 3512 292 java
08:57:36 AM 9391 3499 310 java
8. 常用命令:mpstat 3(Solaris)/pidstat -w -I -p 9391 5(linux版本2.6.23及以上
9.Java程序常用排查锁竞争问题的方法:periodically take thread dumps and look for threads that tend to be blocked on the same lock across several thread dumps。
10. 工具:Oracle Solaris Studio Performance Analyzer(Solaris和Linux)方便锁问题的排查,甚至它能够捕获到CPU缓存的miss率,另外常用的有jstack/pstack命令。
11. Involuntary上下文切换的暗示, High involuntary context switches表明有多于虚拟处理器数的轻量级进程准备去运行,这时伴随着高的运行队列和CPU利用率。优化方法:减少put到CPU的负载,增加CPU,优化数据结构和算法。还有一个可以操作的方法是:linux下使用taskset命令修改进程的“CPU亲和力”,也就是使用taskset充分利用多核CPU,让CPU的使用率均衡到每个cpu上。
12. 线程迁移,通常情况下,CPU调度器会将ready-to-run的线程放到它最后一次被执行的虚拟处理器上,如果该处理器繁忙,那么这个线程会被迁移到其他处理器上。这种线程迁移会影响到性能,因为线程所需要的数据可能在另外的虚拟处理器cache中不存在,故会产生stall延时。
Solaris上mpstat命令的migr”列监控线程是否发生了迁移。优化方法:creating processor sets and assigning Java applications to those processor sets,实际就是上面提到的taskset命令能够做的事情。经验值:在多处理器环境下,如果每秒大于500个迁移可以从“CPU亲和力”设置中获得较好的性能。

你可能感兴趣的:(性能,优化,锁竞争)