請教一下斑竹,關於應用服務器內存佔用比較高的問題 |
答題得分者是:pcplayer99
|
qinmingzsj
一般會員 發表:9 回覆:12 積分:4 註冊:2003-05-08 發送簡訊給我 |
請教一下斑竹,關於應用服務器內存佔用比較高的問題 我使用DELPHI6開發了一個關於三層的C/S企業應用程式,但是根據多日的觀察,發現應用服務器的內存一天一天的增加,因此想請教一下老師針對我的程式是否有好的解決方案. 我具體的架構以及主要的程式如下: 應用服務器: 一: 針對主TRemoteDataModule 1. 主TRemoteDataModule模塊(DM_SERVER),為了將數據庫的連接統一我在DM_SERVER使用了一個TADOConnection (adoCN_Server) 2. 在DM_SERVER中我定義了一個屬性(Connection)以代表adoCN_Server提供給子TRemoteDataModule模塊 具體調用程式: function TDM_SERVER.Get_Connection: Integer; begin Result := Integer(adoCN_Server); end; 3. 在在DM_SERVER中我定義了10個屬性代表10個子TRemoteDataModule提供給客戶端 具體程式(只力例舉了一個): function TDM_SERVER.Get_PQIN_GSD_PACKRM: IQIN_GSD_PACKRM; begin Result := FQIN_GSD_PACKRM.CreateComObject(nil) as IQIN_GSD_PACKRM; Result.MainRm := self; Result.Connection := Get_Connection; end; 4 我定義了一個了被其他子TRemoteDataModule繼承的介面IBASE_RM,在其中我又定義了幾個屬性: MainRm(Read/Write) 取得TRemoteDataModule模塊(DM_SERVER) Connection 取得TRemoteDataModule模塊(DM_SERVER)中的數據庫的連接 5 我定義了10個 子TRemoteDataModule(繼承了IBASE_RM) 在10個 子TRemoteDataModule中我做了如下動作: (只力例舉了一個): 5.1 var FQIN_GSD_PACKRM: TComponentFactory; 作為主TRemoteDataModule獲取子TRemoteDataModule全局變量 5.2 function TQIN_GSD_PACKRM.Get_MainRm: IDM_SERVER; begin Result := FMainDM end; //取得TRemoteDataModule模塊(DM_SERVER) procedure TQIN_GSD_PACKRM.Set_MainRm(const Value: IDM_SERVER); begin FMainDM := Value; end; procedure TQIN_GSD_PACKRM.Set_Connection(Value: Integer);取得數據庫連接 var Icount: integer; begin FCon := Value; for Icount := 0 to ComponentCount - 1 do begin if Components[Icount] is TCustomADODataSet then TCustomADODataSet(Components[Icount]).Connection := TADOConnection(Value); end; end; 10個 子TRemoteDataModule中定義了其他業務邏輯(省略),以及(TADODataSet組件.和相應的DataSetProvider組件)
客戶端: 注明,我在論壇查找過類似此的貼子,但是我按照某些方法還是沒有解決問題.
|
pcplayer99
尊榮會員 發表:146 回覆:790 積分:632 註冊:2003-01-21 發送簡訊給我 |
我猜你的架构是这样:
DataBase <--- ADOConnection <----- ADODataSet <---- xxxx xxxx <--- ClientDataSet 如果是这样,当你的客户端一直向服务器端提交数据,你的 ADODataSet 里的数据会越来越多,当然你的服务器端的 EXE 占用的 RAM 就越来越大。 如果是这样,试一下在半夜没有客户端连接的时候,让服务器端的所有 ADODataSet 都 Close 一下,甚至让 ADOConnection 也 close 一下。 |
pcplayer99
尊榮會員 發表:146 回覆:790 積分:632 註冊:2003-01-21 發送簡訊給我 |
===================引 用 文 章===================
注明,我在論壇查找過類似此的貼子,但是我按照某些方法還是沒有解決問題. ------------------------------ 另外,如果你有 200 个客户端,可能你不能用 TRemoteDataModule 来做 N-tier 了,要考虑使用 COM 了。使用COM ,使用无状态对象,才能解决你的问题。 就算使用普通的 COM 模式的 N-tier,客户端也必须采用无状态模式,在从服务器端获取数据后就断开和服务器端的连接,在需要提交数据给服务器端的时候才再次建立连接。这样,真正在同一时间连接服务器端的客户端的数量就没有那么多了。 |
qinmingzsj
一般會員 發表:9 回覆:12 積分:4 註冊:2003-05-08 發送簡訊給我 |
TO:pcplayer99 我猜你的架构是这样: 你說的沒錯,我的架構是這樣,但是我在客戶端每次使用ClientDataSet獲得數據后,服務端的ADODataSet就已經自動關閉了因為我的應用服务器本身就是個無狀態的.這個我已經通過測試沒有問題.但是內存還是不停的增長,我懷疑是不是Result := FQIN_GSD_PACKRM.CreateComObject(nil) as IQIN_GSD_PACKRM;生成的物件沒有釋放,可是我不知道應該在哪里去釋放它! 懇請各位先進在幫我想想辦法
|
qinmingzsj
一般會員 發表:9 回覆:12 積分:4 註冊:2003-05-08 發送簡訊給我 |
===================引 用 文 章===================
注明,我在論壇查找過類似此的貼子,但是我按照某些方法還是沒有解決問題. ------------------------------ 另外,如果你有 200 个客户端,可能你不能用 TRemoteDataModule 来做 N-tier 了,要考虑使用 COM 了。使用COM ,使用无状态对象,才能解决你的问题。
因為架構已經確定,而且有許多成功的商業應用都是使用 TRemoteDataModule ,我想這個應該不是問題,在客戶端我使用的ClientDataSet的FetchOnDemand使得應用服務器是无状态对象,所以原理就是在从服务器端获取数据后就断开和服务器端的连接,在需要提交数据给服务器端的时候才再次建立连接. 不知道我的這個想法是不是不正確,盼請再次援助!!
|
pcplayer99
尊榮會員 發表:146 回覆:790 積分:632 註冊:2003-01-21 發送簡訊給我 |
===================引 用 文 章=================== ===================引 用 文 章===================
注明,我在論壇查找過類似此的貼子,但是我按照某些方法還是沒有解決問題. ------------------------------ 另外,如果你有 200 个客户端,可能你不能用 TRemoteDataModule 来做 N-tier 了,要考虑使用 COM 了。使用COM ,使用无状态对象,才能解决你的问题。
因為架構已經確定,而且有許多成功的商業應用都是使用 TRemoteDataModule ,我想這個應該不是問題,在客戶端我使用的ClientDataSet的FetchOnDemand使得應用服務器是无状态对象,所以原理就是在从服务器端获取数据后就断开和服务器端的连接,在需要提交数据给服务器端的时候才再次建立连接. 不知道我的這個想法是不是不正確,盼請再次援助!!
-------------------------------------------------------
假设你的客户端是用 DCOMConnection 连接服务器端,通常情况下,一个 DCOMConnection 连接,服务器端就会生成一个对应的 TRemoteDataModule 实例,也就要占用相应的记忆体空间。所以,不单是你的 ClientDataSet 使用无状态,而是要让你的 DCOMConnection 的连接关掉,服务器端才会释放那个 TRemoteDataModule 实例。
如果客户端频繁地连接/关掉连接,服务器端就会频繁地 Create 那个 TRemoteDataModule 的实例,则会导致 CPU 拼命跑,也就是说,节约了记忆体空间,但浪费了 CPU 时间。在这样的情况下,如果采用 COM ,并且把 COM 设定位使用 Pool,那么,一个COM 的 TTransactional Data Module(类似一个 TRemoteDataModule)在被 Create 后,当客户端释放连接的时候,它会被放进 Pool 里,而不是被立即释放。另一个客户端连接过来的时候,这个 DataModule 可以去服务它了。这样,同时服务200个客户端,可能只需要在服务器端同时又5个DataModule的实例就够了。 当然,使用 TRemoteDataModule 也可以有 Pool,自己要写一点代码来实现,而不是象 COM 由WINDOWS 系统来实现POOL。这个 POOL,DELPHI 带的 DEMO 里,有例子,你可以参考。
|
qinmingzsj
一般會員 發表:9 回覆:12 積分:4 註冊:2003-05-08 發送簡訊給我 |
===================引 用 文 章=================== 当然,使用 TRemoteDataModule 也可以有 Pool,自己要写一点代码来实现,而不是象 COM 由WINDOWS 系统来实现POOL。这个 POOL,DELPHI 带的 DEMO 里,有例子,你可以参考。 我查看了 DELPHI 带的 DEMO ,但是它所生成的POOLER卻不能用TSocketconnection 連接,只能用Dcomconnection連接,但是當我的客戶端不在APPSERVER所在的電腦上時卻提示"類別未登錄"(我用dcomcnfg卻看不到這個SERVER.POOLER),所以再次請求幫助. 1. 它所生成的POOLER怎樣才能用TSocketconnection 連接 2. 提示"類別未登錄"該怎么辦. 甚盼回答,非常感激
|
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |