您的位置广东网盟 > 文章资讯 > 软件应用 > 编程开发 > VC/VC++ > 文章内容

高性能托管应用程序设计入门知识介绍

作者:佚名  来源:不详  发布时间:2008-7-30 21:40:26

  摘要:从性能的角度来学习 .net Framework 公共语言运行库。学习如何找出托管代码性能的最佳方法,以及如何测量托管应用程序的性能。
  下载 软件开发和玩杂耍

  我们可以将软件开发过程比作玩杂耍。通常,人们在玩杂耍时至少需要三件物品,而对于可以使用的物品数量并没有任何限制。刚开始学习如何玩杂耍时,您会发现在接球和抛球时您看到的是单个的球。随着熟练程度的增加,您会开始将注意力集中在这些球的运动上,而不是集中在每个单个的球上。当您掌握了玩杂耍的方法时,您就会再次将注意力集中在单个球上,一边努力使这个球保持平衡,一边继续抛出其他的球。凭直觉您就可以知道这些球的运动方向,并且也总是能将手放在正确的地方接球和抛球。可是,这与软件开发又有什么类似之处呢?

  不同的角色在软件开发的过程中会“耍弄”不同的三件物品:项目和程序管理人员耍弄的是功能、资源和时间,而软件开发人员则耍弄正确性、性能和安全性。人们在玩杂耍时总是试图使用更多的物品,但只要是学过杂耍的人都会知道,即使只添加一个球都会让在空中保持所有球的平衡变得更加困难。从技术上讲,如果耍弄的球少于三个,那根本就不叫杂耍。作为软件开发人员,如果您不考虑正在编写的代码的正确性、性能和安全性,则说明您根本就没有投入到您的工作中。当您刚刚开始考虑正确性、性能和安全性时,您会发现您每次只能将注意力集中在一个方面。当它们成为您日常工作的一部分时,您会发现您再也不需要将注意力集中在某一个特定的方面,因为此时它们早已融入了您的工作。而一旦掌握了它们,您就能够凭直觉进行权衡,并相应地调整自己的注意点。这就跟玩杂耍一样,关键在于实践。

  编写高性能的代码本身也存在三件物品:设置目标、测量和了解目标平台。如果您不知道代码必须达到的运行速度,那么您又如何知道您完成了呢?如果您不测量和分析代码,那么您又如何知道您已经达到了目标,或为什么没有实现目标呢?如果您不了解目标平台,那么当您没有实现目标时,又如何知道要对什么进行优化呢?这些原则对所有的高性能代码开发过程几乎都适用,不管您以哪种平台作为目标平台都一样。要完成一篇有关编写高性能代码的文章,就必须提到以上这三个方面。虽然这三个方面都同等重要,但是本文的重点在于后两个方面,因为它们适用于编写以 Microsoft? .NET Framework 作为目标平台的高性能应用程序。

  在任意平台上编写高性能代码的基本原则为:

  1、设置性能目标
  2、测量,测量,再测量
  3、了解应用程序的目标硬件和软件平台

  .net 公共语言运行库

  .NET Framework 的核心是公共语言运行库 (CLR)。CLR 为您的代码提供所有的运行时服务:实时[Denver1]编译、内存管理、安全性和大量其他服务。CLR 的设计考虑了高性能的要求。也就是说,您既可以充分利用其性能,也可以不发挥这些性能。

  本文将从性能的角度概要介绍公共语言运行库,找出托管代码性能的最佳办法,还将展示如何测量托管应用程序的性能。本文并不打算对 .NET Framework 的性能特点进行全面讨论。根据本文的目的,文中提到的性能方面的内容将会包括吞吐量、可扩展性、启动时间和内存使用量等。

  托管数据和垃圾回收器

  在以性能为中心的应用程序中使用托管代码时,开发人员最关心的问题之一就是 CLR 内存管理的开销 - 这种管理由垃圾回收器 (GC) 执行。内存管理的开销由与类型实例关联的内存的分配开销、在实例的整个生命周期中内存的管理开销以及当不再需要时内存的释放开销计算得出。

  托管分配的开销通常都非常小,在大多数情况下,比 C/C++ malloc 或 new 所需的时间还要少。这是因为 CLR 不需要通过扫描可用列表来查找下一个足以容纳新对象的可用连续内存块,而是一直都将指针保持指向内存中的下一个可用位置。我们可以将对托管堆的分配看作“类似于栈”。如果 GC 需要释放内存才能分配新对象,那么分配可能会引发回收操作。在这种情况下,分配的开销就会比 malloc 和 new 大。固定的对象也会对分配的开销造成影响。固定的对象是指那些 GC 接到指令在回收操作期间不能移动其位置的对象,通常是由于这些对象的地址已传递到本机 API 中。

  与 malloc 或 new 不同的是,在对象的整个生命周期中管理内存都会带来开销。CLR GC 区分不同的代,这就意味着它不是每次都回收整个堆。但是,GC 仍然需要了解剩余堆中的活动对象的根是否是堆中正在回收的那部分对象。如果内存中包含的对象具有对其下一代对象的引用,那么在这些对象的生命周期中,管理内存的开销将会非常大。

  GC 是代标记和空闲内存的回收器。托管堆包含三代:第 0 代包含所有的新对象,第 1 代包含存活期较长的对象,第 2 代包含长期存活的对象。在释放足够的内存以维持应用程序继续运行的前提下,GC 将尽可能从堆中回收最小的部分。代的回收操作包括对所有下一代的回收,在这种情况下,第 1 代回收也会回收第 0 代。第 0 代的大小会根据处理器缓存的大小和应用程序的分配率动态变化,它用于回收的时间通常都不会超过 10 毫秒。第 1 代的大小根据应用程序的分配率动态变化,它用于回收的时间通常介于 10 到 30 毫秒之间。第 2 代的大小取决于应用程序的分配配置文件,它用于回收的时间也取决于此文件。对管理应用程序内存的性能开销影响最大的正是这些第 2 代的回收操作。

  提示:GC 具备自我调节能力,它会根据应用程序内存的要求对自身进行调节。多数情况下,通过编程方式调用 GC 时,它的调节功能都未启用。通过调用 GC.Collect 来“帮助”GC 通常无法提高您的应用程序的性能。

  GC 可以在回收对象期间重定位存活的对象。如果这些对象比较大,那么重定位的开销也会较大,因此这些对象都将分配到堆中的一个称为大对象堆 (Large Object Heap) 的特殊区域中。大对象堆可以被回收,但不能压缩,例如,这些大对象不能进行重定位。大对象是指那些大于 80k 的对象。请注意,在将来发行的 CLR 版本中此概念可能会有所变化。需要回收大对象堆时,将强制进行完全回收,而且是在回收第 2 代时才回收它们。大对象堆中对象的分配率和死亡率都会对管理应用程序内存的性能开销产

[1] [2] [3] [4] [5] [6]  下一页

Tags:广东网盟  
  •         用户名: 验证码: 验证码,看不清楚请点击刷新验证码 (注“”为必填内容。)


    文章评论: [ 查看全部 ] 网友评论
    关于网盟 | 网站帮助 | 广告合作 | 下载声明 | 友情连接 | 联系方式

    Copyright © 2003-2008 Gdwg.Net. All Rights Reserved .
    中国广东网管联盟设计维护.网站备案:粤ICP备08020875号