ASP中處理#include
發表時間:2023-08-20 來源:明輝站整理相關軟件相關文章人氣:
[摘要]在ASP中處理#include 文件與用編譯高級編程語言,如C/C++處理包含文件,這兩種方法之間有兩個主要區別。第一,ASP不從最終形成的ASP文件中移走那些未涉及到的信息。這是因為ASP獨立于腳...
在ASP中處理#include 文件與用編譯高級編程語言,如C/C++處理包含文件,這兩種方法之間有兩個主要區別。
第一,ASP不從最終形成的ASP文件中移走那些未涉及到的信息。這是因為ASP獨立于腳本引擎,不過多地進行代碼
分析。大體說來,如果遇到了ASP文件的基本語法請求,信息就被緩存(假定緩沖器是打開的)并被發送到適當
的腳本引擎,進行進一步的分解、標記及執行。
除了這個“死碼”問題,ASP包含文件與編譯語言之間的另一個區別在于:每個ASP文件都可以被看作它自己
的程序。只要一個頁面不包含另一個,在ASP的意義上看來它們就沒有關系,盡管二者對整個站點的運行都很
關鍵。因此,被兩個不同頁面所共享的一個#include 文件必須要被兩個文件都完全包含。從本質上說,ASP不具
備許多高級語言所具備的連接器的優勢,連接器可以用來避免包含文件中代碼和數據的冗余。
如果把我所概括的ASP包含文件的問題組合起來,結論就是:它對一個大型站點的內存將是破壞性的。想象
一下這種情況:一個包含文件中包含了可能要用到的所有共享程序。按照這種設計,導致的結果是所有的ASP頁
都必須包含這一關鍵的文件。如果EverythingButTheKitchenSink.inc 經過分解之后與ASP文件的平均長度相同,
那么被ASP分配并為緩存的ASP文件使用的內存中的一半都充滿了本來多余沒用的信息。
813
調用NT Task Manager/Processes 可以看到正被站點所使用著的內存,并觀察一下多少內存是由mtx.exe
(如果站點被設置成獨立的程序在IIS4上運行),dllhost.exe (如果站點被設置成獨立的程序在IIS5上運行),
或是inetinfo.exe (如果不是獨立的,見下面的圖)這些程序所使用。想要掌握內存增加得有多快,一個很好的
測試方法是啟動IIS后調用一個簡單的頁面來看看內存的大小。(看內存之前要調用一個ASP文件,因為在處理第
一個ASP文件時要建立一些普通的通用文件),F在在你的站點上使用其它ASP文件,并監控每一個被使用的ASP文
件對內存的作用。
比如說我創建了ASP文件。第一個文件RunFirst.asp,是一個小文件,在觀察內存之前初始化ASP資源。另外
兩個文件除了它們所要使用的#include 文件信息不同以外,是完全一樣的。將這些文件復制到你的wwwroot目錄下,
然后按順序運行RunFirst.asp, HelloWorld1.asp和 HelloWorld2.asp,執行HelloWorld1.asp和HelloWorld2.asp
之后觀察內存,你會發現后者使用了更多的內存。這是因為它使用的#include 文件中有一個很大的未使用的程序,
BigAndUnreferenced, 它對頁面的運行結果沒有任何作用,但卻占據了400K的內存。在Windows 2000 Server
w/ IIS5 上依次進行下列步驟得到的結果是:
運行RunFirst.asp 后內存6,104K
運行HelloWorld1.asp后內存 6,124K
運行HelloWorld2.asp后內存 6,544K
僅僅按照這個順序沒有什么明顯的意義,顛倒裝載順序之后的結果是:
運行 RunFirst.asp 后內存6,096K
運行 HelloWorld2.asp后內存 6,536K
運行 HelloWorld1.asp 后內存6,540K
請注意開始和結束的內存數不完全一致,因為內存管理器根據最近的請求大塊地分配內存。但是相對而言,
最終的輪廓總是HelloWorld2.asp 占據大塊的內存份額。本文結尾處可以下載這些簡短的代碼。瀏覽以下這些
代碼,但要分清內存的不同:
RunFirst.asp 是這樣的:
< %@ LANGUAGE="VBSCRIPT" % >
< HTML >
< HEAD >< TITLE >Seed Page to load general ASP resources< /TITLE >< HEAD >
< BODY >
< %
Response.Write "Seed Page Loaded"
% >
< /BODY >
< /HTML >
HelloWorld1.asp 是這樣的:
< %@ LANGUAGE="VBSCRIPT" % >
< !--#include virtual ="/HelloWorld1.inc"-- >
< HTML >
< HEAD >< TITLE >Hello World using little memory< /TITLE >< HEAD >
< BODY >
< %
SayHello
% >
< /BODY >
< /HTML >
HelloWorld1.inc代碼是:
< %
Sub SayHello
Response.Write "Hello World 1"
End Sub
% >
HelloWorld2.asp代碼是:
< %@ LANGUAGE="VBSCRIPT" % >
< !--#include virtual ="/HelloWorld2.inc"-- >
< HTML >
< HEAD >< TITLE >Hello World using a lot of memory< /TITLE >< HEAD >
< BODY >
< %
SayHello
% >
< /BODY >
< /HTML >
但是HelloWorld2.inc要大一些:
< %
Sub SayHello
Response.Write "Hello World 2"
End Sub
Sub BigAndUnreferenced
' This does a lot of redundant stuff to increase memory
Dim textVar
textVar = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"
' this line is duplicated 1,000 times
End Sub
% >
本文中對內存資源的討論是以緩沖器打開為前提的。如果緩沖器沒有打開,那么每個ASP文件集中裝載頁面
的所有組成部分,頁面執行之后再釋放這些內容。多數站點都在一定程度上打開緩沖器,因為大量點擊的站點
的運行請求這樣的要求。即使由于某種原因不打開緩沖器,仍可能受到#include 文件問題的影響,表現為內存波動較
大和處理速度慢。
這里有一些技巧供你參考使用,如:
重新構造包含文件
重新構造包含文件可能是目前你所能做的最容易的事。列出所有包含文件,查找問題的以下跡象:
○ #include 文件是否包含著多種函數?內存效率最高的包含文件應該是特定函數的,以減少死碼的可能性。
例如一個處理日期和時間的包含文件,可以把它分成兩個文件,各處理一個方面:一個單獨的ASP只需要處理一種
類型。
○ #include 文件是否專門存儲整個應用程序所公用的常量?這類文件,根據其大小,可以導致問題發生,
因為通常它們需要被包含在所有的其它包含文件中,就造成了包含文件嵌套?梢詫⒊A糠胖迷谒鼈兯玫
包含文件中。如果常量是ASP文件內部需要的,就可以創建與它們的使用種類有關的較小的常量文件。
○ #include 文件中是否包含作廢的函數?有些函數/程序是站點過去使用過的,已經過了使用期限還掛在那里。
如果在不可預見的未來某一時間,有可能再次使用它們,就應該創建一個小心存檔的文檔文件,說明該函數/程序從
哪里來,何時被移走的,而不是將他們留在活動文件中。版本控制系統對清除舊資源也有所幫助,因為它很容易
被覆蓋。
○ 你對第三方包含文件了解充分嗎?因為涉及到內存問題,你應該明白你的包含文件有多大(甚至于那些你
沒有直接創建的)并且判定一下是否真的需要它們。
你也許會想,這些削減和修改是否在實際上增加了包含文件的數量,在ASP文件中需要更多的#include聲明?
在大多數情況下,答案是肯定的。這是更好地使用包含文件的代價,但是一旦完成了最初的轉換,就不會增加管
理ASP文件的難度。
將代碼放入對象中
也許你正在經歷由#include 而引起的內存膨脹,好在可以在站點中用對象多做一些工作。如果你堅持在
腳本中執行函數,可以考慮使用Scriptlet 。在ASPToday站點和其它刊物上有許多文章討論這些技巧。Scriptlet
可以很好地減少所使用的包含文件的數量:大部分代碼寫完后,從包含函數到它在對象中的封裝之間的過渡
相當容易。只需要圍繞現有代碼的幾句額外的語法和調用方法的一些改變,就完成了對象。另一個優勢在于
scriptlet對象本身就可以被共享,從而進一步減少內存需求。
如果你想要更大的改變,可以考慮可以移植到更快的編譯語言,如like VB, VC++/ATL, 或 Delphi 上的
函數。這樣一來你的應用程序速度真的得到了提高,因為這時所執行的是最優化的代碼而不是解釋腳本。這種
轉變的復雜性顯然依所選語言而不同。比如說,從VBScript 到 VB 就非常直接,而從VBScript 到 VC++/ATL
就復雜多了。可以先作成scriptlet,然后取幾個這樣的新對象并將它們移到編譯語言中去。最好的選擇要么
是很大的對象,它可以節省內存,要么就是使用最頻繁的對象,它可以相當地提高性能。
不管你使用什么語言,使用對象都可以幫助IIS優化管理機器資源,因為這時是在MTS 下運行,并利用它的
所有優勢:連接pooling、對象共享及其它。
利用Server.Execute 和 Server.Transfer (僅限于ASP3/IIS5)
有一個好消息是Microsoft已經認識到了這些問題,正在用IIS5帶的ASP3提供解決這些問題的新技術。有
兩種新的服務器方法可以把你從過多的包含文件中解脫出來。它們使用同一個自變量:ASP文件名。Server.Execute
調用所提供的ASP文件,執行并返回調用者。Server.Transfer 將控制轉換到提供的ASP文件,但不返回。兩個
調用運行文件的方式就好象它們在調用者ASP應用程序內。最后這一點很重要,因為現有的文件規定可以從其它
應用程序中調用ASP文件。
這些調用的思路是將公用的程序放入ASP文件中,然后在其它ASP文件中需要的地方直接執行它們。這類似于
動態的#include ,在調用頁中不使用額外內存。他們非常有效,因為執行的獨立的ASP文件,擁有被緩存和被
共享的一切有利條件。而對包含文件中的公用程序而言,每個使用它們的ASP文件都要裝載并要保留一份拷貝。
Server.Execute 的一個很好的特點是運行條件包含的能力。通常情況下包含不能是有條件的,因為#include
指示是在腳本代碼執行處理條件之前預先處理的。但是用Server.Execute 可以寫出這樣的代碼,查看一個
session變量,決定調用哪一部分代碼,而不是總是裝載著兩部分代碼。
If Session("DoThisOrThat") = "this" Then
Server.Execute("this.asp")
Else
Server.Execute("that.asp")
End If
如果IIS5發行后很快你就能使用(甚至于在此之前,如果你敢在你的站點上使用試用版的話),那么你就
不用為削減你的包含文件而太擔心,相反應該把時間花在模塊化成可直接調用的ASP文件上,或者象上面所說
的將代碼移入對象中。
總結
包含文件的核心思想是:它們是共享代碼的最簡單方式之一,并且能簡化模式站點的設計。我曾經使用過的所
有的先進編程語言都有共享源文件的方法,ASP腳本模型也不例外。一個通用的規則是,傾向于使用包含文件而不是克
隆代碼,但是考慮到ASP在IIS下處理內存空間的獨特方式,注意到這個問題是值得的。
注意在此提到的在站點縮小占用內存的方法。用Task Manager 或類似的工具來觀察mtx.exe (IIS4),
dllhost.exe (IIS5)或 inetinfo,exe (IIS4/5) 的內存大小。你會因一個效率更高的運行站點受益,你的
系統管理員也會因為節省出來的內存芯片而高興。