读书摘要——第五章

  1. 寻找性能瓶颈:通常性能瓶颈表象是资源消耗过多、外部处理系统的性能不足,或者资源消耗不多,但程序相应速度却达不到要求。资源主要消耗在CPU 、文件IO、网络IO以及内存方面。资源消耗不多,程序响应达不到要求的主要原因是程序代码运行效率不够高、未充分使用资源或程序结构不合理。
  2. CPU消耗分析:在LINUX中,CPU主要用于中断、内核以及用户进程的任务处理,优先级为中断->内核->用户进程。上下文切换,每个CPU(或多核CPU中的每核CPU) 在同一时间只能执行一个线程,LINUX采用的是抢占式调度。当一个线程执行时,到达一定执行时间、线程中有IO阻塞或高优先级线程要执行时,LINUX将切换执行的线程,切换是要存储目前线程的执行状态,并恢复要执行线程的状态,这个过程称为上下文切换。上下文切换过多会造成内核占据较多的CPU使用,使得应用响应速度下降。运行队列,每个CPU核都维护了一个可运行的线程队列,如一个4核的CPU,一个应用启动了8个线程,且都是可运行状态,那么平均分配的情况下,每个CPU中的运行队列里就会有两个线程。运行队列值越大,意味着线程会要消耗越长的时间才能执行完成。建议控制在每个CPU核上运行队列为1~3个。利用率,CPU利用率为CPU在用户进程、内核、中断处理、IO等待以及空闲五个部分使用百分比,这五个值是来分析CPU消耗情况的关键指标。建议用户进程的CPU消耗/内核的CPU消耗的比率在65%~70%/30%~35% 左右。在LINUX 中,可通过top 或 pidstat 方式来查看进程中线程的CPU消耗状况。
  3. 文件IO消耗分析:LINUX在操作文件时,将数据放入文件缓存区,知道内存不够或系统要释放内存给用户进程使用,因此在查看LINUX内存状况时经常会发现可用的屋里内存不多,但cached用了很多,这是LINUX提示文件IO速度的一种做法,如物理空闲内存够用,通常在LINUX上只有写文件和第一次读取文件时会产生真正的文件IO。在LINUX中,主要通过pidstat来查找文件IO的消耗。内核版本2.6.20以后,可通过iostat来查看,但iostat只能查看整个系统文件IO消耗情况,无法跟踪到进程文件IO消耗情况。
  4. 网络IO消耗分析:分布式JAVA应用中,尤其要关注网卡中断是不是均衡地分配到各CPU的 可通过cat/proc/interrupts查看。对于网卡中断只分配到一个CPU的现象,google采用了修改kernel的方法进行修复,或是采用MSI-X 的网卡来修复。在LINUX中可采用 sar来分析网络IO的消耗状况。
  5. 内存消耗分析:JAVA应用对于内存的消耗主要是在JVM堆内存上,在正式环境中,多数JAVA应用都会将-Xms 和 -Xmx设为相同的值,避免运行期要不断申请内存。在LINUX中可通过vmstat ,sar , top , pidstat 等方式来查看swap 和物理内存的消耗情况。对物理内存的消耗,JAVA应用中除了少数几种操作 JVM外物理内存的方法外,大多数都是对于JVM heap 去的消耗。
  6. 程序执行慢原因分析:资源消耗不多,但程序执行仍然慢,多出现于访问量不是非常大的情况下,造成这种现象的原因主要有以下三种:锁竞争激烈,例如数据库连接池;未充分使用硬件资源,如双核CPU的机器,但程序都是单线程串行操作;数据量增长,如数据库中单表数据从100万上涨到1亿,数据库读写速度大幅度下降。可以使用JProfiler等商业工具,跟踪代码执行速度。
  7. JVM调优:JVM调优主要是内存管理方面的调优,包括各个代的大小、GC策略等。代大小的调优,-Xms 和 -Xmx通常设置为相同值,避免运行时要不断地扩展JVM内存空间;-Xmn 决定了新生代空间大小,新生代中Eden , S0和S1 三个区域的比率可通过 -XX:SurvivorRatio来控制;-XX:MaxTenuringThreshold控制对象在经历多少次Minor GC  后才转入旧生代,通常又称为新生代存活周期,此参数只有在串行GC时有效,其它GC方式则由JDK自行决定。避免新生代大小设置过小,避免新生代大小设置过大,避免Survivor区过小或者过大,合理设置新生代存活周期,-XX:MaxTenuringThreshold,默认值为15次。
  8. GC策略的调优:由于SUN JDK 串行GC性能太差,因此在实际场景中使用的主要为并行和并发GC。对于Web 应用而言,在G1还不够成熟的情况下,CMS GC是不错的选择。
  9. 程序调优:CPU消耗严重的解决方法,1)CPU US高的解决方法,对堆线程动作增加Thread.sleep ,释放CPU的执行权,降低CPU的消耗;2) CPU sy 高的解决方法,CPU sy 高的原因主要是线程的运行状态经常切换,最简单的解决方法是减少线程数。对于分布式JAVA应用而言,还有一种典型现象是应用中有较多的网络IO操作或确实需要一些锁竞争机制,如数据库连接池,为了更好的支撑高并发,在JAVA应用中又只能借助启动更多的线程来支撑,对于这种现象,可采用协程Corountime 来支撑更高的并发量。目前主要可用的协程框架为  Kilim。
  10. 文件IO消耗严重的解决方法:1)异步写文件,如写日志,可以用log4j提供的 AsyncAppender 。2)批量读写 。3)限流,将文件IO执行频率控制在一定数量内。4)限制文件大小,为文件做大小限制。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值