COM+及記憶體 |
答題得分者是:johnny2212
|
singend
一般會員 發表:3 回覆:8 積分:2 註冊:2003-07-23 發送簡訊給我 |
想請教各位先進
目前我是用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 發送簡訊給我 |
引言:在COM 的程式寫作中 自己開的方法一定要加(SetComplete/SetAbort)控制交易成功或失敗(在事件中則不必) 混心雜欲 棄修身~唉 發表人 - speedup 於 2004/12/31 09:11:15=============================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;
------
唉~ |
singend
一般會員 發表:3 回覆:8 積分:2 註冊:2003-07-23 發送簡訊給我 |
|
johnny2212
初階會員 發表:34 回覆:65 積分:39 註冊:2003-04-09 發送簡訊給我 |
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 發送簡訊給我 |
|
singend
一般會員 發表:3 回覆:8 積分:2 註冊:2003-07-23 發送簡訊給我 |
|
laodingding
一般會員 發表:1 回覆:5 積分:1 註冊:2005-05-07 發送簡訊給我 |
我现在也遇到同样的问题,现在我们是使用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 發送簡訊給我 |
我现在也遇到同样的问题,现在我们是使用MIDAS,采用WebConnection的连接方式,始终出现客户端连接后,服务器进程不能正常关闭,服务器资源不断上升,且数据库连接始终不能正常断开(如用SocketConnection或DCOMConnection连接则一切正常)!
我试了楼上的解决方案,在我的系统中不根本就不能引用SetCompelete和SetAbort这两个过程,出现这两个过程未定义的错误!
望各位大虾能介绍一下要使用这两个过程所必须引用的单元(我试着引用过Mtsobj和Provider单元,但这两个单元中根本就包含这两个过程的调用)! 我的开发环境是:delphi7.0 MIDAS SQL Server2000 另外还想请问一下:singend
你是用johnny2212的哪一种方式解决的? 谢谢!
|
singend
一般會員 發表:3 回覆:8 積分:2 註冊:2003-07-23 發送簡訊給我 |
嗯..
第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 發送簡訊給我 |
谢谢各位热心帮忙! 现在这个问题已经解决了,我是参照了
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 發送簡訊給我 |
|
laodingding
一般會員 發表:1 回覆:5 積分:1 註冊:2005-05-07 發送簡訊給我 |
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)"
|
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |