您的位置:首页 > 理论基础 > 计算机网络

THttprio连接WebService的内存泄漏问题。

2007-05-11 18:04 267 查看
原来写的一个通过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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: