性能瓶颈分析
高性能的含义:
有的场合高性能意味着用户速度体验,如界面操作。- 适合使用OptimizeIt分析
还有的场合,高吞吐量意味着高性能,如短信。 - 适合使用堆栈分析
还有的场合是二者的结合,如IP电话- 适合使用堆栈分析
性能瓶颈问题产生的源头分析
常见架构和设计问题:
不恰当的线程同步
不良的架构(同步/异步使用不当)
并发设计不当-资源抢占导致的资源竞争, 连接池和线程池等应用不当等
效率低下的通信方式
数据库连接等竞争资源参数设置不当
内存泄漏/不恰当的虚拟机运行参数
缓慢的磁盘/网络 IO
… …
常见编码问题
String +,getByte()的不恰当使用:很多时侯可以使用StringBuf
过大的同步范围
SQL语句设计不当
… …
性能瓶颈分析手段和方法之一-线程堆栈剖析
原理:通过分析JVM线程运行情况,定位性能问题
方法: kill -3 <pid> (UNIX) ctrl+break (windows) 打印出当前的虚拟机的一个运行剖面,进行分析
"WorkerThread-8" ... in Object.wait() ...
... - locked <0xf14213c8> (a Queue) ...
"WorkerThread-10" ... in Object.wait() ...
... - locked <0xf14213c8> (a Queue) ...
"WriterThread-3" ... in Object.wait() ...
... - locked <0xf14213c8> (a Queue) ...
能够发现的性能问题:
(1) 资源争用
(2) 锁的粒度过大
(3) sleep的滥用
适用场合:
识别只有在高负载的时候才出现的性能瓶颈。
多线程场合
不适用的场合:
单操作单线程下的代码段耗时分析,如一次界面点击,感觉迟缓。
性能瓶颈分析手段和方法之一 -两种典型的性能瓶颈的堆栈特征
1.绝大多数线程都在做相同的事情,很少有空闲线程。
如: 90%的Sender线程都在执行callAppender
"smpp02:Sender-108" daemon prio=5 tid=0x59a751a0 nid=0x13fc waiting for monitor entry [6066f000..6066fd88]
at org.apache.log4j.Category.callAppenders(Category.java:185)
- waiting to lock <0x14fdfe98> (a org.apache.log4j.spi.RootCategory)
at org.apache.log4j.Category.forcedLog(Category.java:372)
at org.apache.log4j.Category.log(Category.java:864)
可能的原因:
线程数量过小
锁粒度过大
资源竞争(数据库连接池等)
耗时操作(大量的磁盘IO,最终是串行操作)
2.绝大多数线程处于等待状态,只有几个线程在工作,总体性能上不去。
可能的原因:
系统存在关键路径,该关键路径没有足够的能力给下个阶段输送大量输送任务,导致其他地方空闲
如:在消息分发系统,消息分发一般是一个线程,而处理是多线程,这时候消息分发是瓶颈的话,观察到的线程堆栈就会出现上面的现象。
性能瓶颈分析手段和方法之二 -虚拟机参数调优
原理:
观察垃圾回收情况并且进行调整,使JVM的垃圾回收更加平滑和高效率
方法: Java 命令行中增加 –verbose:gc 运行参数
[Full GC 792332K->412757K(1040896K), 8.9157secs]
[Full GC 799898K->221096K(1040896K), 5.3018secs]
如果每次回收完成后可用的内存持续减少则可能存在内存泄漏。
能够发现的性能问题:
垃圾回收参数设置不合理导致的严重的性能问题.
内存泄漏
可以调节的JVM 垃圾回收参数
IBM JDK:主要参数: -Xconcurrentbackground –Xconcurrentlevel, 以及堆大小。
SUN,HP JDK 主要是 -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction
JVM调优是个系统工程,和运行环境主要是内存配置密切相关,需要酌情配置处理
适用场合:
高负载但实时性要求不高的系统,如 Web 类应用,如移动彩铃应用,以及大容量且实时性要求非常高的系统,比如呼叫类应用。
下列JVM参数可用于获取gc日志
-verbose:gc 或
-Xloggc:filename
一些参考资料
http://www-128.ibm.com/developerworks/cn/java/j-jtp11253/
http://www-128.ibm.com/developerworks/cn/java/j-perf05214/
http://www-128.ibm.com/developerworks/cn/java/j-perf06304/
性能瓶颈分析手段和方法之三 - 性能调优工具
OptimizeIt或JProfile - 提供全面的内存泄漏分析,函数调用CPU时间和内存占用分析
适用场合:
(1) 单操作单线程下的代码段耗时分析,如一次界面点击,感觉迟缓。
不适用的场合:
(1)运行期间,同一段代码被不同线程执行时,由于线程是变化的,无法找出对应的线程。
(2)大容量应用下出现的瓶颈, 因为启动这个工具性能会有几十倍甚至上百倍的的性能下降,难以支撑大容量情况下的测试分析。只有在大容量下出现的锁竞争也许不会出现,频繁的磁盘IO、数据库访问等导致的瓶颈也不会出现。现象不充分暴露,自然也就谈不上分析。
高性能的含义:
有的场合高性能意味着用户速度体验,如界面操作。- 适合使用OptimizeIt分析
还有的场合,高吞吐量意味着高性能,如短信。 - 适合使用堆栈分析
还有的场合是二者的结合,如IP电话- 适合使用堆栈分析
性能瓶颈问题产生的源头分析
常见架构和设计问题:
不恰当的线程同步
不良的架构(同步/异步使用不当)
并发设计不当-资源抢占导致的资源竞争, 连接池和线程池等应用不当等
效率低下的通信方式
数据库连接等竞争资源参数设置不当
内存泄漏/不恰当的虚拟机运行参数
缓慢的磁盘/网络 IO
… …
常见编码问题
String +,getByte()的不恰当使用:很多时侯可以使用StringBuf
过大的同步范围
SQL语句设计不当
… …
性能瓶颈分析手段和方法之一-线程堆栈剖析
原理:通过分析JVM线程运行情况,定位性能问题
方法: kill -3 <pid> (UNIX) ctrl+break (windows) 打印出当前的虚拟机的一个运行剖面,进行分析
"WorkerThread-8" ... in Object.wait() ...
... - locked <0xf14213c8> (a Queue) ...
"WorkerThread-10" ... in Object.wait() ...
... - locked <0xf14213c8> (a Queue) ...
"WriterThread-3" ... in Object.wait() ...
... - locked <0xf14213c8> (a Queue) ...
能够发现的性能问题:
(1) 资源争用
(2) 锁的粒度过大
(3) sleep的滥用
适用场合:
识别只有在高负载的时候才出现的性能瓶颈。
多线程场合
不适用的场合:
单操作单线程下的代码段耗时分析,如一次界面点击,感觉迟缓。
性能瓶颈分析手段和方法之一 -两种典型的性能瓶颈的堆栈特征
1.绝大多数线程都在做相同的事情,很少有空闲线程。
如: 90%的Sender线程都在执行callAppender
"smpp02:Sender-108" daemon prio=5 tid=0x59a751a0 nid=0x13fc waiting for monitor entry [6066f000..6066fd88]
at org.apache.log4j.Category.callAppenders(Category.java:185)
- waiting to lock <0x14fdfe98> (a org.apache.log4j.spi.RootCategory)
at org.apache.log4j.Category.forcedLog(Category.java:372)
at org.apache.log4j.Category.log(Category.java:864)
可能的原因:
线程数量过小
锁粒度过大
资源竞争(数据库连接池等)
耗时操作(大量的磁盘IO,最终是串行操作)
2.绝大多数线程处于等待状态,只有几个线程在工作,总体性能上不去。
可能的原因:
系统存在关键路径,该关键路径没有足够的能力给下个阶段输送大量输送任务,导致其他地方空闲
如:在消息分发系统,消息分发一般是一个线程,而处理是多线程,这时候消息分发是瓶颈的话,观察到的线程堆栈就会出现上面的现象。
性能瓶颈分析手段和方法之二 -虚拟机参数调优
原理:
观察垃圾回收情况并且进行调整,使JVM的垃圾回收更加平滑和高效率
方法: Java 命令行中增加 –verbose:gc 运行参数
[Full GC 792332K->412757K(1040896K), 8.9157secs]
[Full GC 799898K->221096K(1040896K), 5.3018secs]
如果每次回收完成后可用的内存持续减少则可能存在内存泄漏。
能够发现的性能问题:
垃圾回收参数设置不合理导致的严重的性能问题.
内存泄漏
可以调节的JVM 垃圾回收参数
IBM JDK:主要参数: -Xconcurrentbackground –Xconcurrentlevel, 以及堆大小。
SUN,HP JDK 主要是 -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction
JVM调优是个系统工程,和运行环境主要是内存配置密切相关,需要酌情配置处理
适用场合:
高负载但实时性要求不高的系统,如 Web 类应用,如移动彩铃应用,以及大容量且实时性要求非常高的系统,比如呼叫类应用。
下列JVM参数可用于获取gc日志
-verbose:gc 或
-Xloggc:filename
一些参考资料
http://www-128.ibm.com/developerworks/cn/java/j-jtp11253/
http://www-128.ibm.com/developerworks/cn/java/j-perf05214/
http://www-128.ibm.com/developerworks/cn/java/j-perf06304/
性能瓶颈分析手段和方法之三 - 性能调优工具
OptimizeIt或JProfile - 提供全面的内存泄漏分析,函数调用CPU时间和内存占用分析
适用场合:
(1) 单操作单线程下的代码段耗时分析,如一次界面点击,感觉迟缓。
不适用的场合:
(1)运行期间,同一段代码被不同线程执行时,由于线程是变化的,无法找出对应的线程。
(2)大容量应用下出现的瓶颈, 因为启动这个工具性能会有几十倍甚至上百倍的的性能下降,难以支撑大容量情况下的测试分析。只有在大容量下出现的锁竞争也许不会出现,频繁的磁盘IO、数据库访问等导致的瓶颈也不会出现。现象不充分暴露,自然也就谈不上分析。