THttprio连接WebService的内存泄漏问题
THttprio連接WebService的內存泄漏問題。
原來寫的一個通過Webservice讀取數據的程序,用Delphi7開發的,在服務器上運行一段時間就死掉了,測試后發現是內存泄漏,在任務管理器中平均每次連接大概增長幾十K內存,長時間運行后CPU占用率很高,程序停止響應。在國內網站上搜索,關于Delphi連接Webservice的文章本來就很少,內存泄漏相關的更少。不得已看了幾天鳥文,終于找到解決方法。
先說一下我的webservice吧,連接到.Net2.0的webservice,返回一個Dataset。在網上可以找到很多如何用delphi返回.net Dataset的文章,大概就是xmlprovider讀取httprio返回的xml stream,再用clientdataset讀取xmlprovider的數據,有兩個難點,一個是必須用工具生成數據集格式文件*.xtr,本來xml有schemer描述,估計可能是delphi對xmlprovider還支持的不是很好,或者對中文支持不好,所以要自此生成格式文件.另外的難點是delphi默認的soap格式(忘了是什么版本)是.net1.0,2.0的格式變了,所以直接用網上的帖子教的方式只能獲取到schemer,而沒有數據,具體方法是webservice的wsdl描述文件中增加:
initialization
...
? InvRegistry.RegisterInvokeOptions(TypeInfo(MonitorServiceSoap),ioDocument);
這樣才能接收到數據,另外httprio需要用UTF-8來傳送中文.
說了這么多,其實當初用了幾天時間學習怎么用delphi接收.net dataset,現在覺得是浪費時間,自己編寫代碼解析xml其實是最快捷的方法,不過為了識別中文,必須把utf-8轉成ansistring:
? SetLength(s,SOAPResponse.size);
? SOAPResponse.Read(PChar(s)^,SOAPResponse.Size);
? s:=Utf8ToAnsi(s);
解析的代碼就不寫了.
很多e文帖子說到是InvokeRegistry.pas中TInvokableClass在析構函數中沒有釋放內存造成,如下:
destructor TInvokableClass.Destroy;
begin
? FreeAndNil(FSOAPHeaders);
? inherited Destroy;
end;
其實是誤導,因為調試的時候發現HttpRio根本沒有用到TInvokableClass類.
還有一個說到是CreateXMLDocument(在XMLDoc.pas),出了問題,Delphi創建XMLDocument按照從高到低的順序嘗試創建,首先創建xml4的版本,如果失敗再繼續建立低版本的,如果用戶機上沒有安裝msxml4.0,在創建失敗后會丟失內存.作者對代碼做了一些修改,說實話我也看不清楚為什么會造成泄漏,但是作者也提出只要安裝了msxml4.0就沒有問題了,實際上我的機器上已經安裝了,所以如果你懷疑的話可以追蹤進入這個函數看看是不是第一次創建就成功了,來驗證自己是否安裝了xml4.我不知道應該如何檢索自己的xml版本,希望誰知道的話回復一下.
繼續說內存泄漏的問題,問題在于調用webservice方法后返回了某個類型的類,這個類必須手動卸載掉,如下
? mySoap:= GetMonitorServiceSoap(False,httpURL,HTTPRIO1);
? res:=mySoap.webserviceMethord(param);
? FreeAndNil(res);
附:delphi解析.net Dataset的講解文章:
http://community.borland.com/article/0,1410,28631,00.html
Google的論壇上也有很多直接在Google搜索不到的帖子,在俺差不多絕望的時候終于抓到救命稻草了,^_^
http://groups.google.com/?hl=zh-CN
?
總結
以上是生活随笔為你收集整理的THttprio连接WebService的内存泄漏问题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: typedef让p去除了普通变量的C++
- 下一篇: 每年的飞鸽传书5月21日都要进一位老师