改进性能和样式的24个ASP 技巧(5)

技巧 4:避免在 Application 或 Session 对象中缓存非灵活组件

虽然在 Application 或 Session 对象中缓存数据是个好主意,但是缓存 COM 对象可能有严重缺陷。将常用 COM 对象嵌入 Application 或 Session 对象通常具有吸引力。遗憾的是,很多 COM 对象,包括用 Visual Basic 6.0 或更早版本编写的 COM 对象,在 Application 或 Session 对象中存储时将导致严重的瓶颈。

特别是任何非灵活组件,在 Session 或 Application 对象中缓存时将导致性能瓶颈。灵活组件是标记为
ThreadingModel=Both
的组件(它聚集了自由线程汇集器 (FTM))或标记为
ThreadingModel=Neutral
的组件(Windows(R) 2000 和 COM+ 中新增的"中性"模型。)下列组件是非灵活的:

自由线程组件(除非它们聚集了 FTM)。
单元线程组件。
单线程组件。
已配置组件(Microsoft Transaction Server (MTS)/COM+ 库和服务器包/应用程序)为非灵活组件,除非它们是"中性"线程的。单元线程组件和其他非灵活组件最适于在页作用域工作(也就是说,它们在单个 ASP 页上创建和销毁)。

在 IIS 4.0 中,标记为
ThreadingModel=Both
的组件被视为灵活的。在 IIS 5.0 中,这已经不够了。组件不仅必须标记为 Both,而且还必须聚集 FTM。灵活性文章说明了如何使得用"活动模板库"编写的 C++ 组件聚集 FTM。请注意,如果组件缓存接口指针,这些指针本身必须为灵活的、或者必须存储在"COM 全局接口表 (GIT)"中。如果不能重新编译 Both 线程组件,使它聚集 FTM,则可以将该组件标记为
ThreadingModel=Neutral
。另外,如果不希望 IIS 进行灵活性检查(这样,希望非灵活组件能够存储在 Application 或 Session 作用域中),可以在 metabase 中设置
AspTrackThreadingModel

True
。不主张更改
AspTrackThreadingModel

如果试图在 Application 对象中存储用
Server.createObject
创建的非灵活组件,IIS 5.0 将产生错误。可以通过在 Global.asa 中使用
<object runat=server scope=application ...>
解决该问题,但是不主张这样做,因为这将导致汇集和串行化,说明如下。

如果缓存非灵活组件,会发生什么错误呢?缓存在 Session 对象中的非灵活组件,将把会话"锁定"到某个 ASP 工作器线程。ASP 维护着一个工作器线程池,它向请求提供服务。通常,新的请求由第一个可用的工作器线程来处理。如果 Session 被锁定到某个线程,则该请求将不得不等待它所关联的线程变为可用。打个比方:您进入一个超市,挑选了一些食品,然后在第 3 号收款台交款。从这以后,每当您在这个超市购买食品,都不得不始终在第 3 号收款台交款,即使是在其他收款台人少或没人时。

将非灵活组件存储在 Applicaton 作用域甚至会对性能产生更严重的影响。ASP 将不得不创建专用的线程来运行非灵活的、Applicaton 作用域内的组件。这将导致两种后果:所有调用不得不被汇集到该线程,而且所有调用被串行化。汇集意味着:参数不得不存储在内存的共享区;对该专用线程执行昂贵的上下文切换;组件的方法被执行;结果汇集到共享区域;以及经过另一个昂贵的上下文切换,使控制权返回原来的线程。串行化意味着所有方法必须一个挨一个地运行(同一时刻只能运行一个方法)。两个不同的 ASP 工作器线程不可能同时执行共享组件上的方法。这将扼杀并行机制,尤其是在多处理器计算机上。更坏的是,所有非灵活的、Application 作用域内的组件都将共享一个线程("Host STA"),所以串行化的影响更加严重。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/3230.html