1.1 性能概述

关于Java的性能概述,主要介绍说明性能的表现形式以及一些参考指标

性能的主要表现

□ 执行速度:程序反映是否迅速,响应是否足够快。
□ 内存分配:内存分配是否合理,是否有内存泄漏、消耗过多内存。
□ 启动时间:程序从启动运行到可以正常处理业务需要多少时间。
□ 负载承受能力:当系统压力上升时,系统的执行速度、响应时间等上升曲线是否平缓。

性能的参考指标

□ 执行时间:一段代码从开始运行到运行结束所需要的时间。
□ CPU时间:函数或者线程占用CPU的时间。
□ 内存分配:程序再运行时所占用的内存空间。
□ 磁盘吞吐量:描述I/O的使用情况。
□ 网络吞吐量:描述网络的使用情况。
□ 响应时间:系统对用户行为或者某个时间做出的响应时间。响应时间越短,性能越好。

木桶原理与性能瓶颈

木桶原理,也叫“短板理论”,核心内容为:一只木桶能盛多少水,不取决于最长的木块有多长,而是取决于桶壁上最短的那块木板。同样地,将木桶原理的理论应用到系统性能上也还是一样,系统是一个整体,其最终性能取决于系统中性能表现最差的组件。因此,在考虑系统性能的时候,不能总是盯着一个性能研究处理。为了提升系统的整体性能,必须对系统中表现最差的组件进行优化。此时,系统中性能表现最差的组件便成了系统的性能瓶颈。

最有可能成为系统瓶颈的计算资源

□ 磁盘 I/O:由于磁盘 I/O 读写的速度比内存慢很多,程序在运行过程中,如果需要等待磁盘 I/O 完成,那么低效的 I/O 将会拖累整个系统的操作。
□ 网络 I/O:由于网络环境的不确定性,尤其是网络数据的读写,网络 I/O 的速度可能比磁盘 I/O 还慢。
□ CPU:对计算资源要求较高的应用,由于长时间占用大量的CPU资源,导致其他线程或应用产生对CPU资源的争夺,导致性能下降。
□ 异常:在Java应用中,捕获和处理异常是非常消耗资源的。如果程序高频低进行异常处理,那么程序的整体性能也会受到影响。
□ 数据库:海量数据的读写会耗费很长的时间,很慢。而程序可能会需要完成数据库操作才能返回请求结果,那程序的执行时间或者系统响应时间就会被拉长。
□ 锁竞争:在高并发程序中,锁竞争将会明显增加线程上下文切换的开销。而这些开销都是与应用需求无关的系统开销,会占用宝贵的CPU资源,却没有任何好处。
□ 内存:一般来说,能使内存方面制约系统性能的最可能情况就是内存大小不足。

Amdahl定律

Amdahl 定律是计算机科学中非常重要的定律,它定义了串行系统并行化后加速比的计算公司和理论上限。加速比越高,表明优化效果越明显。
加速比定义:加速比 = 优化前系统耗时 / 优化后系统耗时
Amdahl 定律给出了加速比与系统并行度和处理器数量的关系。设加速比为 Speedup,系统内必须串行化的程序比重为 F,CPU 处理器数量为 N,则有:
1 Java性能调优概述 - 图1
根据上诉公式,如果CPU处理器数量趋于无穷,那么加速比与系统的串行化率成反比。如果系统中必须有50%的代码串行执行,那么系统的最大加速比为2。

根据Amdahl 定律分析,使用多核CPU对系统进行优化,优化的效果取决于CPU的数量以及系统中的串行化程序的比重。CPU 数量越多,串行化比重越低,则优化效果越好。如果不降低程序的串行化比重,仅提高CPU数量是无法提高系统性能的。

1.2 性能调优的层次

在实际开发中,除了对代码优化,在软件架构上、JVM虚拟机层、DB(数据库)以及OS(操作系统)层面都可以通过一定的手段进行调优,从到达到整体提升系统性能的目的。

设计调优

设计调优处于所有调优手段的上层,往往在需要软件开发之前进行。在软件设计时,软件架构师应该评估系统可能存在的各种潜在问题,并给出合理的设计方案。因为软件设计和架构设计对软件整体质量有决定性的影响。
注:一个良好的系统设计可以规避很多潜在的性能问题。

代码调优

在软件开发过程中或后期维护过程中进行的对程序代码的改进和优化。包括API、算法、数据结构的使用优化。作者将代码优化称为微观层面上的优化,也是对系统性能产生最直接影响的优化方法。

JVM调优

因为Java程序是在JVM虚拟机上运行,所以对JVM进行优化也能在一定程度上提升程序的性能。通常在软件开发完成或开发过程中某个很重要节点阶段进行优化。
JVM调优手段一般是修改JVM参数以调整堆大小、GC策略等。

数据库调优

□ 对数据库的调优可分为3个部分:
□ 应用层对SQL语句优化,如使用索引查询、避免全表扫描查询
□ 对数据库进行优化,如分库、加索引
□ 对数据库软件进行优化,如设置缓冲区、连接池

操作系统调优

不同类型操作系统,调优的手段和参数可能会有所不同。比如,在上流 UNIX 系统中共享内存段、信号量、共享内存最大值 (shmmax)、共享内存最小值 (shrmmix)等都是可以进行优化的系统资源。此外,如最大文件句柄数、虚拟内存大小、磁盘的块大小等参数都可能对软件的的性能产生影响。

1.3 基本调优策略和手段

系统性能优化的最主要目的就是查找并解决性能瓶颈问题。但同时值得注意的是,性能优化往往会涉及对原有的实现进行较大的修改,因此,很难保证这些修改不引入新的问题。所以,在性能优化前,需要对性能优化的目标、方法进行统筹的安排。

优化的一般步骤

1、明确优化目标,清楚地指出优化的对象和最终目的。
2、在目标平台上对软件进行测试,通过性能监控和统计工具,观测的确认当前性能是否达到预期
3、达到预期,结束优化;未达到预期目的,查找当前性能瓶颈进行优化
可能存在的瓶颈参考 1.1 性能概述。流程图如下图所示;
1 Java性能调优概述 - 图2

系统优化注意事项

性能调优必须有明确的目标,评估调整的风险与收益,并且需要在软件功能、正确性和可维护性间取得平衡,不要为了调优而调优,过分追求系统性能。盲目的进行调整,其风险可能远大于收益。