線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:3344
推到 Plurk!
推到 Facebook!

COM+及記憶體

答題得分者是:johnny2212
singend
一般會員


發表:3
回覆:8
積分:2
註冊:2003-07-23

發送簡訊給我
#1 引用回覆 回覆 發表時間:2004-12-31 01:13:59 IP:218.162.xxx.xxx 未訂閱
想請教各位先進 目前我是用delphi寫client程式 ap為delphi所寫成的com ( 透過ado 及adodsdataset) db則用sqlserver client透過socket連接ap去db做存取 但是每次存取過後,將工作管理員叫出後 dllhost的記憶體總是會增加 當資料較大量、長時間使用及多次連線做存取時曾經將記憶體吃光,並產生空間不足之錯誤訊息 將com 元件停止後重新啟動便又會回覆正常了 不知是不是那裡沒注意到才會導致如此 =============================client程式============================ procedure GetData; var ttArr : OleVariant ttSCKET : TSocketConnection; begin ttSCKET := TSocketConnection.Create(nil); ttSCKET.Address := '127.0.0.1'; ttSCK.ServerGUID := '{32CDA575-.......}'; ttSCK.ServerName := 'pjCOM.COMN'; ttSCK.Open; ttSCK.AppServer.GetAllData(ttArr); ttSCK.Close; ttSCK.Free; ttSCK := nil; end; ===================================================================== COM 程式 procedure TbObjectN.GetAllData(var ppArr: OleVariant); var ttI, ttCount : Integer; begin try ttCount := 0; adods.Close; adods.commandtext := 'select * from TempDB'; adods.open; adods.First; if adods.Recordcount > 0 then begin ppArr := varArrayCreate([0, adods.fieldCount-1, 0, adods.Recordcount-1], varVariant); while not adods.Eof do begin for ttI := 0 to adods.FieldCount-1 do begin ppArr[ttI, ttCount] := adods.Fields[0].Value; end; Inc(ttCount); adods.Next; end; end; adods.close; except on E : Exception do adods.Close; end; end;
speedup
資深會員


發表:19
回覆:259
積分:280
註冊:2003-07-04

發送簡訊給我
#2 引用回覆 回覆 發表時間:2004-12-31 09:09:26 IP:220.135.xxx.xxx 未訂閱
引言:
=============================client程式============================
procedure GetData;
var 
  ttArr : OleVariant
  ttSCKET : TSocketConnection;
begin 
  ...
  {ttSCKET.Open;}ttScket.Connected:= True;//你應該誤寫
  ttSCKET.AppServer.GetAllData(ttArr);
  {ttSCKET.Close;}ttScket.Connected:= False;//你應該誤寫
  ttSCKET.Free;
  ttSCKEt := nil;
end;
=====================================================================
COM 程式
procedure TbObjectN.GetAllData(var ppArr: OleVariant);
var
  ttI, ttCount : Integer;
begin
  try
    ttCount  := 0;
    adods.Close;
    adods.commandtext := 'select * from TempDB';
    adods.open;
    adods.First;
    if adods.Recordcount > 0 then begin
      ppArr := varArrayCreate([0, adods.fieldCount-1, 0, adods.Recordcount-1], varVariant);
      while not adods.Eof do begin  
        for ttI := 0 to adods.FieldCount-1 do begin 
          ppArr[ttI, ttCount] := adods.Fields[0].Value;
        end; 
        Inc(ttCount);
        adods.Next;
      end;
    end;
    adods.close;
    SetComplete;
  except on E : Exception do 
    setAbort;
    adods.Close;
  end;
end;
在COM 的程式寫作中 自己開的方法一定要加(SetComplete/SetAbort)控制交易成功或失敗(在事件中則不必) 混心雜欲 棄修身~唉 發表人 - speedup 於 2004/12/31 09:11:15
------
唉~
singend
一般會員


發表:3
回覆:8
積分:2
註冊:2003-07-23

發送簡訊給我
#3 引用回覆 回覆 發表時間:2004-12-31 09:49:32 IP:203.70.xxx.xxx 未訂閱
謝謝speedup 大大 但 ttSOCKET.Open = SetConnected(True); 那請教各位先進 ttSOCKET.Open 與ttSOCKET.Connection := True 有何不同?效能上是否也會不同呢? 另外,我也試過在com 的method中 加上SetComplete;及setabort的語法 但是記憶體還是往上跑
johnny2212
初階會員


發表:34
回覆:65
積分:39
註冊:2003-04-09

發送簡訊給我
#4 引用回覆 回覆 發表時間:2005-01-01 23:08:15 IP:61.226.xxx.xxx 未訂閱
1 TempDB這個Table有沒有建Primary key,若沒有的話您先建立 後再試試看,若記憶體沒往上跑就OK了(Table要建key,不然記憶體會 無法釋放) 2 若還是不行,您更改Com 的部分,先用以下兩個寫法試試看 (因為我沒看過傳資料庫的資料,會用陣列的寫法,好像太麻煩了) function TbObjectN.GetAllData1: OleVariant; //function的建立應該會吧 ,Modifier選擇 RetVal begin ClientDataSet1.CommandText:='select * from TempDB'; ClientDataSet1.Open; Result:=ClientDataSet1.Data; ClientDataSet1.Close; end. procedure TbObjectN.GetAllData2(ppArr: OleVariant); //看看這個方法,ppArr應該會釋放資源 begin ClientDataSet1.CommandText:='select * from TempDB'; ClientDataSet1.Open; ppArr:=ClientDataSet1.Data; ClientDataSet1.Close; end. Client端的部分 若接 function ClientDataSet1.Data:=ttSCK.AppServer.GetAllData1; 若接procedure ttSCK.AppServer.GetAllData(ttArr); ClientDataSet1.Data:=ttArr; 3 若還是不行,就加入SetCompelete, SetAbort,將Com 改成需要交易,再試試看 如果記憶體還是釋放不掉,我就真的沒法度了
singend
一般會員


發表:3
回覆:8
積分:2
註冊:2003-07-23

發送簡訊給我
#5 引用回覆 回覆 發表時間:2005-01-04 17:15:25 IP:203.70.xxx.xxx 未訂閱
謝謝johnny2212大大 我試了你的方法 果然記憶體吃的比較少 不會像以前那樣一路往上爬 但是仍會小漲一翻,只是比率小很多了
singend
一般會員


發表:3
回覆:8
積分:2
註冊:2003-07-23

發送簡訊給我
#6 引用回覆 回覆 發表時間:2005-01-04 17:17:02 IP:203.70.xxx.xxx 未訂閱
謝謝johnny2212大大 我試了你的方法 果然記憶體吃的比較少 不會像以前那樣一路往上爬 但是仍會小漲一翻,只是比率小很多了
laodingding
一般會員


發表:1
回覆:5
積分:1
註冊:2005-05-07

發送簡訊給我
#7 引用回覆 回覆 發表時間:2005-06-08 14:50:26 IP:218.18.xxx.xxx 未訂閱
我现在也遇到同样的问题,现在我们是使用MIDAS,采用WebConnection的连接方式,始终出现客户端连接后,服务器进程不能正常关闭,服务器资源不断上升,且数据库连接始终不能正常断开(如用SocketConnection或DCOMConnection连接则一切正常)! 我试了楼上的解决方案,在我的系统中不根本就不能引用SetCompelete和SetAbort这两个过程,出现这两个过程未定义的错误! 望各位大虾能介绍一下要使用这两个过程所必须引用的单元(我试着引用过Mtsobj和Provider单元,但这两个单元中根本就包含这两个过程的调用)! 我的开发环境是:delphi7.0 MIDAS SQL Server2000 另外还想请问一下:singend 你是用johnny2212的哪一种方式解决的? 谢谢! 發表人 - laodingding 於 2005/06/08 15:03:31
laodingding
一般會員


發表:1
回覆:5
積分:1
註冊:2005-05-07

發送簡訊給我
#8 引用回覆 回覆 發表時間:2005-06-08 15:07:36 IP:218.18.xxx.xxx 未訂閱
我现在也遇到同样的问题,现在我们是使用MIDAS,采用WebConnection的连接方式,始终出现客户端连接后,服务器进程不能正常关闭,服务器资源不断上升,且数据库连接始终不能正常断开(如用SocketConnection或DCOMConnection连接则一切正常)! 我试了楼上的解决方案,在我的系统中不根本就不能引用SetCompelete和SetAbort这两个过程,出现这两个过程未定义的错误! 望各位大虾能介绍一下要使用这两个过程所必须引用的单元(我试着引用过Mtsobj和Provider单元,但这两个单元中根本就包含这两个过程的调用)! 我的开发环境是:delphi7.0 MIDAS SQL Server2000 另外还想请问一下:singend 你是用johnny2212的哪一种方式解决的? 谢谢!
singend
一般會員


發表:3
回覆:8
積分:2
註冊:2003-07-23

發送簡訊給我
#9 引用回覆 回覆 發表時間:2005-06-09 09:41:29 IP:61.66.xxx.xxx 未訂閱
嗯.. 第2點我有試過,確實是可以將記憶體的漲幅降低 但是後來 由於架構的問題,所以暫時無法將寫法全面改成第2點的方式 後來找到原因是:由於我們仍是用Array傳回,因為一開始將陣列內的所有傳回值全部用Variant的方式來接(如:ppArr[0, i]= adods.fields['id'].value); com 不管你再怎麼回傳,一定會在ap上留下同樣一份的記憶體大小 所以,ppArr[0, i]= adods.fields['id'].value的這種方式,傳回的是Variant形態,它的size又占的暫大,因此只要欄位一多,又多人查詢,記憶體便會往上飆漲。 所以,我們解決方式便是這欄位或是int,我們就用asInteger的形態傳回,依其欄位特性來回傳,就避免掉了這個問題。但記憶體仍是會往上小漲一點點,不像一開始的情況,laodingding建議你可用johnny2212大大所提供的第2點試試。
laodingding
一般會員


發表:1
回覆:5
積分:1
註冊:2005-05-07

發送簡訊給我
#10 引用回覆 回覆 發表時間:2005-06-10 10:30:18 IP:218.18.xxx.xxx 未訂閱
谢谢各位热心帮忙! 现在这个问题已经解决了,我是参照了 http://qc.borland.com/wc/qcmain.aspx?d=2297 上的解决办法; 现在客户端资源可以正常释放,数据库连接也可以正常断开! Added early exit Need to modify sConnect.pas TWebConnection = class(TStreamedConnection, ITransport) ... protected procedure SetConnected(Value: Boolean); override; // Add this procedure TWebConnection.SetConnected(Value: Boolean); var i : integer; begin if Value = Connected then Exit; if not Value then begin with TDataBlockInterpreter(FInterpreter) do for i := FDispatchList.Count - 1 downto 0 do begin FInterpreter.CallFreeObject(TDataDispatch(FDispatchList[i]).DispatchIndex); FInterpreter.RemoveDispatch(TDataDispatch(FDispatchList[i])); end; end; inherited; end; 改了这个单元后,重新编译客户端应用程序;然后问题就可以解决; 但大家要非常注意一点; 改了这个单元后,所以连接的客户端必须一次性更新,即所有连接用户都必须用改SCONNECT.PAS文件编译的客户端,如果在网络中同时存在更改SCONNECT.PAS文件前编译的客户端和更改SCONNECT.PAS文件后编译的客户端,则会产生问题,当更改SCONNECT.PAS文件前编译的客户端运行后,更改SCONNECT.PAS文件后编译的客户端则不能正常连接,所以大家一定要注意,更改该单元后,后有的客户端必须同时更新为新的应用程序,否则就有苦头受了!
abc123
一般會員


發表:0
回覆:1
積分:0
註冊:2002-05-30

發送簡訊給我
#11 引用回覆 回覆 發表時間:2005-08-20 17:09:27 IP:219.144.xxx.xxx 未訂閱
但是更重要的BUG大家还没有发现码?服务器登录了一定的次数后,或者说多个用户登录、退出,没有多长时间,就成了单用户:最后只能让一个用户登录,第二个用户登录出现错误:"Could not convert variant of type (Dispatch) into type (Integer)"
laodingding
一般會員


發表:1
回覆:5
積分:1
註冊:2005-05-07

發送簡訊給我
#12 引用回覆 回覆 發表時間:2005-11-01 11:01:22 IP:61.141.xxx.xxx 未訂閱
I also encounter this HUGE problem,  What shall I do< >< > <>< face="Verdana, Arial, Helvetica">引言: 但是更重要的BUG大家还没有发现码?服务器登录了一定的次数后,或者说多个用户登录、退出,没有多长时间,就成了单用户:最后只能让一个用户登录,第二个用户登录出现错误:"Could not convert variant of type (Dispatch) into type (Integer)"
系統時間:2024-03-29 20:41:15
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!