UML软件工程组织

 

 

使用 Rational PurifyPlus 进行运行时分析的介绍

2008-05-05 作者:Goran Begic,Allan Pratt 来源: IBM

 
本文内容包括:
本文来自于 Rational Edge:本文讨论了其他 Rational 最佳实践中的运行时分析,并概述了其对软件开发人员、测试人员,和管理人员所带来的巨大好处。

 运行时分析是一种基于观察系统运行时行为的实践。它与"静态分析"不同,静态分析是指通过观察源代码或高级架构分析系统行为;或是分析系统失败时的"崩溃分析。"

调试是一种经典的运行时分析的例子:设置断点,一步步地运行系统,并且观察评估值和变量,通过这些方法了解系统运行时所发生的情况。当您调试的过程中,您不会对所有可能发生的事情感兴趣,仅仅对真正发生的感兴趣。这正是将运行时分析从静态分析中分离出来的原因。

调试过程是高度互动且有效的,但它受限于所能展示的内容。当您将关注的焦点集中于一行或一个变量时,它很难识别出模式并综合高级行为。

测试是另一种运行时分析:您通过数据或事件检验是否获得来自系统的正确行为。这种类型的测试是软件质量的基础。

传统的测试仅仅为您展现出这么多。一个通过了所有测试(获得正确结果)的系统仍然具有严重的质量问题。

这些就是为什么类似于 IBM Rational PurifyPlus 的运行时分析工具诞生的原因。

什么是 PurifyPlus?

PurifyPlus 是一种运行时分析工具,它用以在系统运行时监测系统并且报告系统行为的重要内容:

  • 它会使用多少内存?
  • 是否会造成内存泄露?
  • 是否包括内存访问错误?
  • 需要多长时间启动;瓶颈在哪里?
  • 什么是线程运行/睡眠行为?
  • 实际运行的源代码有多少?

这些关键分析特征都与核心"正确性" 问题无关:"是否能够运行?"和"是否产生正确结果?" 测试能够显示您的系统是否正常工作,利用类似于 PurifyPlus 的运行时分析工具能够发现所有类型的错误。

PurifyPlus 的主要组件有:

  • 内存使用追踪及内存错误检测
  • 量化的性能分析、代码流和线程可视化
  • 源代码覆盖分析的 PureCoverage

系统开发周期中的运行时分析

交互的开发周期和工程质量方案中重要的自动化构建、测试过程中都会包含运行时分析。

开发与执行过程中的运行时分析

在交互开发过程中,Purify 能够在新代码加入工程前报告内存错误。开发人员能够使用 PureCoverage 识别所需新测试的区域。Quantify 能够在开发早期展现未期望的代码路径和瓶颈。

自动化测试过程中的运行时分析

当运行自动化构建测试时,PurifyPlus 能够使您监测质量并且收集信息以确保工程处于正轨。当您的测试运行于 Purify 且没有错误报告时,您就可以知道系统并不含有内存访问错误和内存泄露。 当所运行的 Quantify 显示性能满足目标时,您可以知道系统没有遇到瓶颈。当 PureCoverage 报告高级别的代码覆盖时,您可以知道并没有引入新的代码块,因此不必增加自动测试。

您可以增加利用自动化测试工具(IBM Rational Functional Tester)所获得的运行时分析数据的质量。自动化的测试能够在一次叠代中得到更多的测试信息,并且能够评估所引入的新产品质量效果。如果软件质量介于两类连续的组件叠代间,那么运行时分析数据很容易找出其中的特点或代码的改变。

用以理解系统的运行时分析

有时,运行时分析并不包括正确性或质量。例如,运行时分析可以帮助理解系统。尤其是,Quantify 能够展示出调用图,揭示系统的各个部分如何协调工作,或揭示了非期望的性能下降或交互。

基本的 PurifyPlus 能力

如上所述,IBM Rational PurifyPlus 具有三个主要组件:内存分析的 Purify,性能分析的 Quantify,和代码覆盖分析的 PureCoverage。

对于 C/C++ 程序,Purify 自动化的检测并报告内存泄露和内存访问错误,例如,在内存释放后使用内存,重复释放相同区域的内存,或是初始化前从内存读。所有这些都是潜伏于程序中的软件质量问题,即使通过了所有测试。这类错误可以导致严重的生产错误。

对于 Java 和 Microsoft .Net 程序("已管理的程序"),Purify 追踪内存的使用和内存引用,因此,您能够发现哪里是内存瓶颈,应在哪里释放内存,比对前后图形以检测程序中未预料的内存使用 ("泄露")。

Quantify 追踪程序性能和调用行为,因此您能够发现执行流并识别出瓶颈。 Quantify 强调了使用 River of Time(tm)特征的花费最久的代码路径。除此之外,Quantify 为您可视化的实现了线程执行行为。

PureCoverage 追踪代码覆盖,因此您可以发现测试与运行时分析工具不能发现的鸿沟。由于 Purify 和 Quantify 仅仅看到了实际运行的代码,PureCoverage 提供的代码覆盖矩阵重点了解正在检测和更新的质量。

使用 PurifyPlus 的运行时分析的例子

调试的主要目标就是找出缺陷的根本原因并理解程序行为。

运行时分析提供了额外的补充传统调试不足的能力:

  • 应用执行的可视化。
  • 重要运行时参数的度量,包括内存使用、性能和代码覆盖。
  • 用户模式下的错误检测。
  • 运行时行为的文档。

我们将在下面检查这些能力。

应用执行的可视化

为理解这一能力,我们将看到以下四个例子。

可视化例子1:代码覆盖

使用诸如 Rational® PureCoverage® 的运行时工具(包含于 Rational PurifyPlus 中)提供了各种视图展现代码覆盖信息,其中之一就是 Annotated Source。这一特别的视图显示了所检查的应用的源文件;划线的颜色指出了执行测试事例之后的状态:hit、 missed、 dead 或部分 hit。

如图 1所示,用户能够看到测试样例的代码覆盖和执行路径。

Rational PurifyPlus Display of Annotated Source for the C#.NET application in Visual Studio.NET

图 1: Rational PurifyPlus 在 Visual Studio.NET 中显示了 C#.NET 样例
点击放大

图 1中的代码段显示了第 111 行执行交换陈述时所应用的准确路径。这一特殊行被标记为部分 hit,因为第 122 行没有执行。

可视化例子 2:线程

运行时分析工具诸如 Rational Quantify (包含于 Rational PurifyPlus中)提供了线程可视化,它能够利用标记调试时每个线程的状态检测多线程问题。如图2所示,它允许您在调试时检测可视化线程的状态。

Rational Quantify Thread Analysis View in Visual Studio 6

图 2: Visual Studio 6 中的 Rational Quantify 线程分析视图
点击放大

可视化例子 3:调用图

运行时分析工具还能够检测和显示性能瓶颈。这种方法与传统方式相比最大的优势就在于,您可以获得完美的执行路径概况,和关于调用数准确信息。如图 3A 和 3B 所示,Rational Quantify 中的 Call Graph 强调了最大时间消耗执行的路径的调用链;那就是性能弱点。连接方法的粗线表示了调用链所花费时间和剩余应用时间(如果使用 Purify,那就是内存)的比率。

Rational Quantify Call Graph of a Mixed VB.NET and C#.NET Application in Visual Studio.NET

图 3A: Visual Studio.NET 中 VB.NET 和 C#.NET 应用的混合 Rational Quantify 调用图
点击放大

Rational Quantify Call Graph of a C/C++ Application on Solaris

图 3B: Solaris 中 C/C++ 应用的 Rational Quantify 调用图
点击放大

可视化例子 4:内存使用

处理内存泄露的第一步就是要检测。一种直观的方式就是可视化全部内存使用并且在测试(PUT)下进行内存快照。这可以在运行中的应用中发现潜在的内存泄露。(在 Rational Purify for Java 和 .NET 管理应用中已经实现)例如,如果对于在服务器端运行的组建内存快照显示,全部内存性能在客户端增加,之后很可能是组件泄露(见图 4)。

Overview of Thread Status and Memory Usage in Rational Purify for Windows

图 4:Rational Purify for Windows 中的线程状态和内存使用概况
点击放大

关键运行时参数的测量

可见的错误检测仅仅是运行时分析的第一步。我们还需要准确理解运行时所发生的事情。因此,运行时分析应基于针对应用执行的准确的参数测量:

  • 运行时性能
  • 内存使用
  • 代码覆盖

我们将再次通过事例理解这一运行时分析的能力。

测量实例 1:函数列表视图

函数列表视图是一种典型的运行时分析视图,它能够由特殊的运行时分析工具(如 Rational Quantify)创建(见图 5)。它显示了表中全部重要的方法和/或应用对象;这样就允许了开发人员通过分析代码找出最佳的使用内存的方法,同时可以找出最慢的函数,对象生存时间,等等。

这一视图提供了关于方法调用总数,方法的时间花费,所选方法的时间花费和内存积聚,及其全部派生的准确信息。

Rational Quantify Function List View for a Visual C++ Application

图 5:针对 Visual C++ Application 的 Rational Quantify 函数列表视图
( 点击放大 )

测量实例 2: 函数详细视图 Function 详细视图

运行时分析工具(例如 Rational Quantify)还能够扩展测量实例 1 中的信息,使它包括了调用方法和派生间的测试数据的分布信息。如 Function Detail View (图 6)所示。 这一视图强调了对于性能或内存热点(能够用以帮助检测准确的性能或内存瓶颈的原因的信息)有意义的调用者和派生。

Figure 6

图 6:Visual Studio.NET (使用 IBM Rational XDE)中的针对 Visual C#.NET 的 Rational Quantify 函数详细视图
点击放大

测量实例 3:方法覆盖模块视图

正如先前我们所解释的,在一些实例中--尤其是评估可用测试方法价值时,它对于测量测试过程所覆盖的代码比率,或简单的标记所有未测试的方法是十分有用的。您可以应用诸如 Rational® PureCoverage®的工具,用以产生准确的未测试和废弃代码与已测试代码的信息(图 7)。

Figure 7

图 7:Visual Studio.NET (使用 IBM Rational XDE)中对于 C#.NET 和 VB.NET 应用程序的混合方法代码覆盖的 Rational PureCoverage 显示
点击放大

错误检测:用户模式下的运行时内存崩溃

这是对于纯 C/C++ 应用的运行时分析的最高荣耀。运行时分析不但能通过显示性能、内存、线程和不同视图中的代码覆盖数据检测错误,还能够在用户模式下准确的指出产生和/或引起错误的位置。运行时内存崩溃检测能够确保所有平台上的正确函数和高质量的纯 C 和 C++ 应用程序。对于运行时内存检测的 IBM Rational 工具有 Rational Purify 和Rational PurifyPlus。让我们再来看看一些例子。

错误检测实例 1: Rational Purify 内存错误和内存泄露报告

Rational Purify 能够指出开发人员创建的农村错误的准确代码行。它甚至不需要源文件就可以提供这一信息; Rational Purify 在内存中检测错误,并使用调试信息追踪回溯找出相应的代码行(见图 8)。

Rational Purify Memory Error and Memory Leak Report for a Visual C++ Application

图 8: 针对 Visual C++ 应用的Rational Purify 内存错误和内存泄露报告
点击放大

在这个例子中,开发人员忘记构建数组变量时考虑终止符。这一错误将会导致应用构造的崩溃,而调试构造却很正常。本例仅仅是运行时分析减少 C/C++开发调试时间的一个例子。

错误检测实例 2:量化标注源

Rational Quantify 具有一种独一无二的能力,它能够为用户方法代码的每一行测量记录的时间分布。量化标注源显示了每行代码的测量时间,和调用这行所花费的时间。这类信息能够有助于将性能瓶颈缩小到代码行级别(图9)。

Rational Quantify Annotated Source for a Mixed Visual Basic 6 and Visual C++ Application in Visual Studio 6

图 9: Visual Studio 6 中针对混合的 visual Basic 6 和 Visual C++ 应用的 Rational Quantify 标注源
点击放大

错误检测实例 3: Purify 对象和指针图

在 Java 和 .NET 管理代码中,不可能产生诸如读写边界溢出和读写释放内存的运行时内存错误,因为运行时子系统的自动内存管理机制禁止开发人员直接访问所分配的内存。但是,这种自动化的内存管理并不能阻止程序员忘记对象指针分配内存。只要代码中存在这种动态分配对象的指针,他们将存在于内存中并不会被自动化的内存管理(垃圾回收技术)所清除。这种错误的影响与 C/C++ 中的泄露是一样的:内存对于其他运行于主机操作系统中的进程变得不可访问。但是通过使用 Rational Purify 的运行时分析,您能够指出发生问题的对象指针的准确代码行(图 10)。

Rational Purify Object and Reference Graph for a Java Application

图 10:针对 Java 应用的 Rational Purify 对象和指针图
点击放大

运行时行为的文档

另一种平衡运行时分析的方式是对未来的应用进行运行时行为的文档化操作。这样可以帮助您评估工程的全部质量,并测量新引入特征、应用性能、可靠性、完整性所带来的影响。 这种实际运行时分析的方式包含了开发和分析数据下的对每次组件或应用叠代的收集运行时数据。这些信息有助于确定工程质量,附加新特征与错误定位的效果。

当您使用了运行时分析工具和源控制工具(如 IBM Rational® ClearCase®),您可以很容易的检测到哪些源代码数据库的改变对于错误的构造和/或自动化测试的失败有关;您能够发现在成功测试与失败测试间的源代码库的改变。不仅仅是:能够识别那些改变代码的归属者和引入的准确时间和日期。

高级的运行时分析工具(如 Rational PurifyPlus )提供了分析多重测试运行的特征,例如,允许用户混合各种不同测试的代码覆盖数据,或为连续测试叠代创建单独的数据集合,如图 11所示。

Rational Quantify Compare Runs Report

图 11: Rational Quantify 比对运行报告
点击放大

图 11中, Rational Quantify 比对了两类数据集,并强调了性能改进的调用链(绿线)和性能下降的调用链(红线)。最后的数据可以从 Call Graph 视图和更详细的 Function List 视图中获得。

即使您没有创建自动化的测试环境,您仍然可以通过利用存储为 ASCII 文件的运行时分析数据创建自动化的数据分析。图 12 显示了一个导入到 Microsoft Excel 中的性能概况的例子。

Rational Quantify Performance Report Imported into Excel

图 12:Rational Quantify 性能报告被导入到 Excel 文件中
点击放大

您可以在 Excel 中通过创建简单的 Visual Basic 程序很容易的实现自动化的数据分析,或以任何流行的脚本语言:Perl, WSH, JavaScript,等等。PurifyPlus for UNIX 包含了脚本集,能够帮助您管理和分析来自各种测试的数据。

运行时分析:重点是质量

运行时分析扩展了一维标准软件开发行为:质量关注。它通过更好的理解应用的内部工作过程实现了更高的软件质量。记住:编译的源代码不能证明质量;细节的、可靠的、准确地运行时性能、内存使用和线程与代码覆盖分析数据是唯一的决定应用程序不含严重错误并且高效执行的标准。

参考资料

 

组织简介 | 联系我们 |   Copyright 2002 ®  UML软件工程组织 京ICP备10020922号

京公海网安备110108001071号