软件性能与性能测试Word格式文档下载.docx
《软件性能与性能测试Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《软件性能与性能测试Word格式文档下载.docx(13页珍藏版)》请在冰豆网上搜索。
从开发人员的角度来说,会关心主要的用户感受—响应时间,因为这毕竟是用户的直接体验;
另外,开发人员也会关心系统的扩展性等系统管理员所关心的内容,这里指的是性能而不是功能的可扩展性,这个问题本文的后面讨论;
但对开发人员来说,最想知道的是“如何通过调整设计与代码等等方法来提高软件的性能表现”与“如何发现并解决软件设计与开发过程中产生的由于多用户访问引起的缺陷”等等,参见表1。
表1给出了开发视角的软件性能关注内容。
开发人员关心的问题问题所属环节
架构设计是否合理?
系统架构
数据库设计是否合理?
数据库设计
代码是否存在性能方面的问题?
代码
系统中是否有不合理的内存使用方式?
系统中是否存在不合理的线程同步方式?
设计与代码
系统中是否存在不合理的资源竞争?
设计与代码从表1中可以看到,问题所属的关键环节是在代码构建上面。
从开发人员的角度来看,可以用如下五个方面来作为评判性能的标准:
1运算的性能——哪一个算法的执行性能最好?
2内存的分配——程序运行时需要耗费多少内存?
3启动的时间——程序启动需要多长时间?
这在Web项目中的影响不大,但要注意部分程序需要部署或运行在客户端时的情形(比如Applet程序。
4程序的可伸缩性——在压力负载的情况下,程序的性能如何?
5性能的感知——用户在什么情况下会觉得程序的性能不好?
以上五个方面,在具体的使用场景可以有选择的去评判。
关于如何提高系统性能的问题,我们在下节进行讨论。
2.如何提高程序的性能
要提高软件的性能,我们可以从以下几个方面着手,
使用高性能、速度快的硬件--$$$=速度
使用恰当的编程语言与进行编译器优化
设计可扩展的应用程序
架构设计方面
选择正确的数据结构与算法
代码调整
避免使用较慢的OSAPIs
调整、测量(注意是测量而不是测试、再调整、再测量…
(1从上面的几个方法来看,使用高性能、速度快的硬件很容易理解,也是决大多数人在碰到性能问题的时候首先会想到的办法。
采取这样的方法总是很有效的吗?
(2使用恰当的编程语言与进行编译器优化也是提高软件性能的方式之一。
例如在使用IntelC++编译器时,编译器选项可以组合。
每种优化各有其特点,尝试着各种优化选项的效果,有时各种优化选项组合使用可能效果更好。
使用时,这些选项加到ProjectSetting对话框中。
如图1所示。
图1
同样,在原则Java语言构建软件系统时,可以针对JDK进行调优。
例如:
选择合适的JDK版本:
不同版本的JDK,甚至不同厂家的JDK可能都存在着很大的差异,对于性能优化的程度不同。
一般来说,尽可能选择最新发布的稳定的JDK版本。
最新的稳定的JDK版本相对以前的JDK版本都会做一些bug的修改与性能的优化工作。
垃圾收集:
垃圾收集就是自动释放不再被程序所使用的对象的过程。
当一个对象不再被程序所引用时,它所引用的堆空间可以被回收,以便被后续的新对象所使用。
垃圾收集器必须能够断定哪些对象是不再被引用的,并且能够把它们所占据的堆空间释放出来。
如果对象不再被使用,但还有被程序所引用,这时是不能被垃圾收集器所回收的,此时就是所谓的“内存泄漏”。
监控应用程序是否发生了内存泄漏,有一个非常优秀的监控工具推荐给大家——Quest公司的JProbe工具(这样的工具非常多,有许多是开源的,使用它来观察程序运行期的内存变化,并可产生内存快照,从而分析并定位内存泄漏的确切位置,可以精确定位到源码内。
这个工具的使用我在后续的章节中还会做具体介绍。
Java堆的优化:
Java堆是指在程序运行时分配给对象生存的空间。
通过
-mx/-Xmx与-ms/-Xms来设置起始堆的大小与最大堆的大小。
根据自己
JDK的版本与厂家决定使用-mx与-ms或-Xmx与-Xms。
Java堆大小决
定了垃圾回收的频度与速度,Java堆越大,垃圾回收的频度越低,速度
越慢。
同理,Java堆越小,垃圾回收的频度越高,速度越快。
要想设置
比较理想的参数,还是需要了解一些基础知识的。
Java堆的最大值不
能太大,这样会造成系统内存被频繁的交换与分页。
所以最大内存必须
低于物理内存减去其他应用程序与进程需要的内存。
而且堆设置的太
大,造成垃圾回收的时间过长,这样将得不偿失,极大的影响程序的性
能。
在效率方面,程序的效率与详细设计阶段确定的算法的效率直接有关。
在详细设计翻译转换成源程序代码后,算法效率反映为程序的执行速度与存储容量的要求。
要从计算复杂性、内存的使用、数据依赖性等多方了解,使用如何实现算法指导起一个重要作用。
而数据的依赖性与指令的选择密切相关,以Intel86x指令结构为例:
选择指令
需要实现一种算法的指令可能对性能有一个大的影响。
因此检测采用某个算法中的某些指令,像整数加法可能执行两个/s,还执行其
它指令;
像整数除法,可能每23Clock才能执行一次。
由于不同的
指令有不同的延迟与吞吐量,指令的速度是一定的。
指令输入准备好以后(预取来自内存,指令的延迟是要求执行开始并完成一条指令的时钟数。
整数乘大约15-18Clock。
所有,
乘法的响应在它开始执行以后有可利用的15-18Clock。
指令的吞吐量是开始执行相同的指令之前处理器要求等待的时钟数。
指令的吞吐量总是少于或等于指令的延迟。
乘法的吞吐量是
5Clock,意味着新的乘法可能开始执行每5Clock,即使它花费
15-18Clock去响应任何指定的乘法。
指令流水线引起吞吐量与延迟
的Clock数是不同的。
数据的依赖性与指令的平行性
数据的依赖性影响处理器的同步执行指令的能力,它能提高算法的性能。
Pentium处理器是能够每个Clock执行六条指令,但由于指令流的问题,同步执行指令数经常是较低的。
理想的情况如图2所示:
图2
图2这是假设这些指令之间没有数据依赖性存在,允许它们同时进行,只有指令的延迟与吞吐量的限定。
在实际情况下,数据依赖性往往存在,并且这会使结局有巨大的不同,如图3所示:
在图3中,数据的依赖性与延迟限制指令的平行性对算法性能来说是关键的限制因素。
补充指令平行性规则对各个已存在的处理器家族已有说明,但用数据依赖性与延迟解释能产生一个稍微好些的执行指令,可以忽略补充指令平行性规则。
图3
对于线程的监控可以借助很多工具来完成,图4是采用JProfiler对线程进行的监控例子。
乘法:
a=u*vb=w*xc=y*za=u*vb=w*xc=y*z
延迟乘法:
a=w*x*y*zw*x
y*zwx*yz
图4
(3设计可扩展的应用程序:
指的是软件性能上的可扩展。
这点可能会使很多读者感到很困惑,难道还有哪些设计会造成使用更高速度的硬件不能提高软件的性能吗?
答案是肯定的,如果一个软件设计的不具备可以扩展性,那么在4个、8个CPU的机器上运行会比在1个CPU的机器上运行的速度快不了多少。
让我们用一个例子来说明这个问题。
这是一个SMPT服务器的例子,为了说明问题,我们将该邮件服务器的实现进行高度抽象(实际要复杂的多。
这个服务器的基本功能就是:
发邮件,来邮件后进行处理,分析邮件发给谁,如果发给是本机的邮箱的人员就给把它直接拷贝到一个邮箱中去。
如果是传送的另外一个SMPT服务器的,就通过TCPIP把它给转发出去。
高度抽象后的抽象SMPT服务器
//ReadSMTPcommands/datafromsockets--首先把邮件从sockets读进来
If(ReadFile(…
{//varioushousekeepingremoved…}
//ParseSMTPrecipientsandotherheaders--分析读进来的邮件,先分析头文件(地址,来源的信息
If(!
ParseSMTPHeaders(…{
//handleerrors…
}
//Parsebodies--然后分析文件的bodies
ParseSMTPBodies(…{
//Localdeliveryorrouting–做判断
If(LocalDelivery(…{--本机
Deliver(…;
拷到一个目录下
}else{下一极SMTP服务器
Route(…;
转发到另外的SMTP服务器
//SendSMTPresponsethroughSocket
If(WriteFile(…{
//varioushousekeepingskips…写文件或Socket穿到另外的服务器}
传统的线程的设计方法是这样做的:
1threadtoreceiveanddispatchSMTPrequest
64workerthreadsdoing:
(64个工作线程去做剩余的4个步骤
ParseSMTPheaders
ParseSMTPbodies
Localdelivery
Routing
每一个线程都一步一步的依次做这4个步骤,然后在做下一个,不断的
重复。
这样的设计其性能就不具备可扩展性,如果感到邮件服务器的处理能力不够,通过增加CPU是无法提高其处理能力的,为什么呢?
前面在讲到效率的时候,我们说要从内存的使用等方面进行考虑。
下面我们看看相关硬件对这个设计的影响。
我们都知道,对于存储来说,存取速度的快慢从高到低的顺序是:
L1cache->
L2cache->
RAM->
。
因此,如果我们的代码从硬盘上读入进入cache后能够很好的在cache存放,你的程序的不断的被重用,不断的被执行的运行,你的效率就会非常的高。
而如果你的大不分程序都要经常从硬盘、从内存读入后执行,那么你的程序效率当然就会很低了。
而且你也知道,虽然这些年CPU、内存的速度增长很快,但是硬盘的读写速度并没有多大的提高。
这里有个比喻:
如果1秒钟可以清零一个寄存器这样的简单操作,那么:
在L1cache中操作–只需要1秒(1倍
在L2cache中操作–需要4秒(plus3secondsextrawork-7倍
在RAM中操作--需要25-150秒(24倍-150倍
在磁盘中操作–则需要3个周(2,000,000倍
因此我们的设计应该充分的利用cache或内存,这样程序的效率才能够得到高性能。
SMPT服务器的全新设计是:
1threadtoreceiveanddispatchSMTPrequest(与原来的设计一样
2workerthreadperCPU
剩余的4个步骤,每个步骤对应一个队列,线程每一次都把一个队列的全部工作都做完后,才做其它的步骤。
ParseSMTPheaders/bodies
Socketsendand
这样一来,有什么好处呢?
很显然,对于每一个步骤来说,数据是不一样
的,但是程序是相同的,每次都处理一个队列中的所有内容,因此程序得到了不断的重用。
图5给出了两个设计的效果比较。
图5
(4代码的调整:
代码优化的方法有许多,针对不同的环境、编程语言等都有特定的有关优化方法,可以参照相关资料,例如在Java编程方面可以看看《JavaPerformanceTuning》》(O'
Reilly这本书。
代码是要在个编程过程中不断进行调整的,因此调整、测量、再调整、再测量…。
通过不断的测量找出需要进行性能优化的部位,那么在开发中如何进行测量,采用怎样样的方法、工具就显得极为重要了,这方面的问题我们将在本文的后面详细讲述。
持续性能检测、监视与改进代码,这样容易做到性能优化,而且还可以有效的发现与改进性能。
而等到最后才开始优化性能,会变得更困难与费时。
3.有关软件性能的基础知识
(1多进程
多进程是在同一个系统中执行多个进程或程序的能力,多进程的主要好处是提高系统的吞吐量。
某些应用依赖多进程去优化吞吐量。
如:
同时有许多用户登录系统。
从硬件的角度,提高性能最容易的方法是在主板上放入多于一个的CPU,这样不同的CPU既可以承担不同的工作,又可以使它们平行运行,做相同的工作。
在一个对称多进程环境中,CPU共享相同的内存,在一个CPU中运行的代码可能影响另一个CPU使用内存,其结果会受影响。
你不能确定早先你给变量设定的值仍是原值,因另一个CPU可能对它做了操作。
(2多线程
多线程是一个进程在相同的地址空间里同时执行多道线程,这些线程有不同的执行路径与独立的堆栈,也可能线程有相同的执行路径而操作不同的数据。
一个线程打印,一个线程计算并存或同一个应用计算用多个线程,各自有不同的数据等。
系统支持多线程可以改进各个应用的性能。
(3加速
加速是调整后的性能与原性能之比,或它是基线的测量性能与优化后的性能的典型计算之比。
当你设置调整目标与测量改进性能时,它是有用的。
加速通常有两种表示方法:
(4可测量性
可测量性是隐藏在应用与系统中的一种能力,由增加资源数量来提高性能。
如:
向系统中加入更多的处理器、更多的RAIDs、或更多的磁盘组成RAID,应用程序性能会更好。
两种可能的方法检验是否应用是可计量的:
固定负载,用增加CPU提高性能增加CPU,增加负载来维持性能
(5“Amdahl”定律的图形表示与公式
图6
Time=
BaselineTimeOptimizedTimeRate=OptimizedTimeBaselineTime
Speed-UpofFractionEnhanced
(1-FractionEnhanced+FractionEnhancedSpeed-Up=1
如果仅有一半的执行时间被优化,2倍的加速是不可能的。
4.主要主要性能指标性能指标性能指标种类种类
(1并发用户数(Concurrentuserssupported
并发用户数是指在某一给定时间内,某个特定点上进行会话操作的用户数。
网站的公式网站并发用户数公式如下:
网站并发用户数=RPS+SBC+ThinkingTime
这里:
RPS(RequestPerSecond每秒请求数(吞吐量
SBC(SimultaneousBrowserconnections并发连接数
ThinkingTime平均用户思考时间
(2响应时间(Responsetimeorlatency
响应时间指的是客户端发出请求到得到响应的整个过程所经历的时间。
例如从初始的请求到回应下载的完成(刷新整个网页之间的时间,参见图7。
图7
你可以测试在服务器上与在客户端上的响应时间:
服务器端的响应时间(Latencymeasuredattheserver这个时间指的是服务器完成请求执行的时间,不包括客户端到服务器端的反应(请求与反应在网络上的通讯时间
客户端的响应时间(Latencymeasuredattheclient这个反应时间等于客户端的请求队列加上服务器的反应时间与网络的反应时
间。
你可以用各种各样的方法来测试反应时间。
常用的有两种方法:
首
字节响应时间(度量首字节的响应时间,指向服务器发送请求与接收到
响应的第一个字节之间的时间与末字节响应时间(度量末字节的响应
时间,指向服务器发送请求与接收到响应的最后一个字节之间的时间。
通过测量响应时间,您能知道您的应用程序是否因为响应时间太久以至于不能响应请求。
(3吞吐量(Throughput
吞吐量是指单位时间内系统处理的客户请求的数量,直接体现软件系统的性能承载能力。
一般来说,吞吐量由负载(如用户的数量或使用什么类型的应用程序来决定(举个例子,下载文件比浏览网页需要更高的吞吐量。
如吞吐量用请求数/秒或页面数/秒来衡量,从业务的角度,吞吐量也可以用访问人数/天或处理的业务数/小时等单位来衡量。
从网络的角度来说,也可以用字节数/天等单位来考察网络流量。
(4资源利用率
资源利用率是指系统资源的使用程度,比如服务器的CPU利用率、内存利用率、磁盘利用率、网络带宽利用率等。
1内存(Memory
内存使用情况可能是系统性能中最重要的因素。
如果系统“页交换”频繁,说明内存不足。
“页交换”是使用称为“页面”的单位,将固定大小的代码与数据块从RAM移动到磁盘的过程,其目的是为了释放内存空间。
尽管某些页交换使操作系统能够使用比实际更多的内存,也是可以接受的,但频繁的页交换将降低系统性能。
减少页交换将显著提高系统响应速度。
要监视内存不足的状况,请从以下的参数指标开始:
CommittedBytesinUse(正在使用的字节的百分比:
是Memory_CommittedBytes与Memory_CommitLimit之间的百分比比值,
即已分配给物理RAM用于存储或分配给页面文件的虚拟内存。
Available
Bytes(可用物理内存数:
显示了物理内存的剩余量。
该值
低于4MB,并且达到分钟级时,表明内存不足
PageFaults/sec(每秒钟的缺页数:
该数值反映了有多少个请求的信息不在物理内存中对应的位置上。
该值偶尔高时,表明有线程竞争,持
续走高时,表示可能有内存瓶颈。
Pages/sec(显示pageinput/sec与pageoutput/sec的总与:
pageinput/sec反映的是物理内存的短缺情况;
pageoutput/sec显示从物
理内存中调出的信息量,反映了计算机的繁忙程度。
一般如果Page/sec
持续高于几百,那么您应该进一步研究页交换活动。
有可能需要增加内
存,以减少换页的需求(你可以把这个数字乘以4k就得到由此引起的
硬盘数据流量。
Page/sec的值很大也不一定就表明内存有问题,而
可能是运行使用内存映射文件的程序所致。
由于过多的页交换要使用大
量的硬盘空间,因此有可能将导致将页交换内存不足与导致页交换的磁
盘瓶径混淆。
因此,在研究内存不足不太明显的页交换的原因时,您必
须跟踪磁盘使用情况(在下面介绍计数器与内存计数器:
PageFaults/sec包括有些可以直接在内存中满足而有些需要从硬盘读取,而page/sec只表明数据不能在内存的指定工作集中立即使用。
2磁盘(PhysicalDisk
DiskTime:
所选磁盘驱动器忙于为读或写入请求提供服务所用的时间的百分比。
如果三个计数都比较大,那么硬盘不是瓶颈。
如果只有%Disk
Time比较大,另外两个都比较适中,硬盘可能会是瓶颈。
IdleTime:
磁盘空闲时间的百分比
Avg.DiskQueueLength:
指读取与写入请求(为所选磁盘在实例间隔
中列队的的平均数。
该值应不超过磁盘数的1.5~2倍。
要提高性能,
可增加磁盘。
注意:
一个RaidDisk实际有多个磁盘
CurrentDiskQueueLength:
指在收集操作数据时在磁盘上未完成的请求的数目。
它包括在快照内存时正在为其提供服务中的请求。
这是一
个即时长度而非一定间隔时间的平均值
如果页面读取操作速率很低,同时DiskTime与Avg.DiskQueueLength的值很高,则可能有磁盘瓶径。
但是,如果队列长度增加的同时页面读取速率并未降低,则内存不足。
3处理器(Processor
ProcessorTime:
指处理器执行非闲置线程时间的百分比。
如果该值持续超过95%,表明瓶颈是CPU。
可以考虑增加一个处理器或换一个更快的处理器。
UserTime:
指用于用户模式的非闲置处理器时间的百分比。
例如在耗费CPU的数据库操作中,如排序,执行aggregatefunctions等。
如果该值很高,可考虑增加索引,尽量使用简单的表联接,水平分割大表格等方法来降低该值。
ProcessorQueueLength:
处理器队列长度。
队列长度持续大于4则表示可能出现处理器拥塞。
此计数器是特定时间的值,而不是一段时间的平均值。
4网络
BytesTotal/sec:
网络带宽利用率,为发送与接收字节的速率,包括
帧字符在内。
判断网络连接速度是否是瓶颈,可以用该计数的值与目前网络的带宽比较,若要在传送量中留些空间供尖峰时间用,则不应常使用超过50%的容量。
如果这个数字十分接近连接的容量,而处理器及内存的使用都很适中,则此连接也会是个问题。