DELPHI盒子
!实时搜索: 盒子论坛 | 注册用户 | 修改信息 | 退出
检举帖 | 全文检索 | 关闭广告 | 捐赠
技术论坛
 用户名
 密  码
自动登陆(30天有效)
忘了密码
≡技术区≡
DELPHI技术
lazarus/fpc/Free Pascal
移动应用开发
Web应用开发
数据库专区
报表专区
网络通讯
开源项目
论坛精华贴
≡发布区≡
发布代码
发布控件
文档资料
经典工具
≡事务区≡
网站意见
盒子之家
招聘应聘
信息交换
论坛信息
最新加入: webb123
今日帖子: 32
在线用户: 18
导航: 论坛 -> DELPHI技术 斑竹:liumazi,sephil  
作者:
男 jopher3 (樵夫的马六甲) ▲▲▲▲▲ -
普通会员
2016/11/21 13:24:16
标题:
慎用FireDAC组件,有内存泄漏! 浏览:4111
加入我的收藏
楼主: TFDQuery或TFDStoredProc,经过许多次使用(Create、Open、转Cds、Close、Free)之后,会产生内存泄漏。本人经过了好多个晚上长时间测试、观察后得出的结论。Delphi 10.1版本。

相同的方法,ADO、UniDAC都没问题,不会泄漏。

所以,假如用FireDAC写两层的客户端程序,马马虎虎,可以不用关注此问题;而用于写三层的话,请一定慎重,让你的程序连续不断执行任务,跑它一天,同时观察内存占用情况!
----------------------------------------------
樵夫的大马甲
作者:
男 vga (vga) ★☆☆☆☆ -
盒子活跃会员
2016/11/21 13:51:33
1楼: 向楼主致敬!!!
----------------------------------------------
-
作者:
男 bjeco (eco) ▲▲▲▲△ -
普通会员
2016/11/21 14:01:13
2楼: 是不是“转Cds”引起的泄露?
去掉 “转Cds”,楼主再测一下
----------------------------------------------
-
作者:
男 jopher3 (樵夫的马六甲) ▲▲▲▲▲ -
普通会员
2016/11/21 14:05:32
3楼: 通过TDatasetProvider转换的,ADO、UniDAC也一样转!

Dsp.dataset:=fdquery;
Cds.data:=dsp.data;

但是,FireDAC,就是会有内存泄漏!ADO、UniDAC不会
----------------------------------------------
樵夫的大马甲
作者:
男 jopher3 (樵夫的马六甲) ▲▲▲▲▲ -
普通会员
2016/11/21 14:08:45
4楼: 俺也尝试使用FDQuery的对象池,大幅减少Create/FreeAndNil的次数,但是,内存泄漏问题依然存在!
----------------------------------------------
樵夫的大马甲
作者:
男 grjs_2004 (grjsITname) ★☆☆☆☆ -
盒子活跃会员
2016/11/21 14:38:15
5楼: 呵呵!你可能还不太了解FireDAC的数据处理原理吧!
因为其不会自动清理内存,需要用户自己确定不用的数据对象,自己去释放;
所以不管你用对象池还是其他方法,在确定不再使用时,进行及时清理。
其他如ADO,UniDAC可能有自动清理的机制,但是很多时候需要你进行判断是否已经创建了相同的数据对象,存储在内存里
----------------------------------------------
Everyone will to do best!
作者:
男 earthsbest (全能中间件) ▲▲▲▲△ -
普通会员
2016/11/21 15:18:15
6楼: 我用FireDAC在服务端跑了几年了,妥妥的的。FireDAC有着优良数据格式,天生适合做三层开发。
此帖子包含附件:
PNG 图像
大小:49.7K
----------------------------------------------
Delphi4Linux Delphi三层/FireDAC 技术群:734515869 http://www.cnblogs.com/rtcmw
作者:
男 blueflag (昆了) ★☆☆☆☆ -
盒子活跃会员
2016/11/21 15:30:50
7楼: 反正这些query 不用就释放,用了就创建,还是挺好的习惯~
----------------------------------------------
-
作者:
男 foryour (sean) ★☆☆☆☆ -
普通会员
2016/11/21 15:36:47
7楼: remark
----------------------------------------------
-
作者:
男 jopher3 (樵夫的马六甲) ▲▲▲▲▲ -
普通会员
2016/11/21 15:52:52
8楼: //
// 线程主函数...
procedure TReadThread.Execute;
var
   q: TFDQuery;
begin
   while not terminated do
      begin
         q:=TFDQuery.Create(nil);
         q.Connection:=FDConn;
         try
          q.SQL.Text:='Select * from customers order by customerid';
          q.Active:=true;
          synchronize(success);
         Except
          synchronize(fail);
         end;
         FreeAndNil(q);
         sleep(100);
      end;
end;
----------------------------------------------
樵夫的大马甲
作者:
男 jopher3 (樵夫的马六甲) ▲▲▲▲▲ -
普通会员
2016/11/21 15:53:18
9楼: 就这么一段,运行几千次,就很明显的泄漏!
----------------------------------------------
樵夫的大马甲
作者:
男 jopher3 (樵夫的马六甲) ▲▲▲▲▲ -
普通会员
2016/11/21 15:55:08
10楼: 代码发生来了,可以印证!
此帖子包含附件:jopher3_2016112115558.rar 大小:53.4K
----------------------------------------------
樵夫的大马甲
作者:
男 jopher3 (樵夫的马六甲) ▲▲▲▲▲ -
普通会员
2016/11/21 16:00:26
11楼: 各位印证吧,别说我瞎逼逼
----------------------------------------------
樵夫的大马甲
作者:
男 jopher3 (樵夫的马六甲) ▲▲▲▲▲ -
普通会员
2016/11/21 16:27:19
12楼: 我改成了对象不再经常创建/释放的形式,即类似对象池的形式,内存泄漏依旧存在!
说明内存泄漏来自FireDAC组件的底层。

同样,上代码,请大伙验证!
此帖子包含附件:jopher3_20161121162718.rar 大小:53.5K
----------------------------------------------
樵夫的大马甲
作者:
男 jopher3 (樵夫的马六甲) ▲▲▲▲▲ -
普通会员
2016/11/21 16:32:44
13楼: 呵呵!你可能还不太了解FireDAC的数据处理原理吧!
因为其不会自动清理内存,需要用户自己确定不用的数据对象,自己去释放;
所以不管你用对象池还是其他方法,在确定不再使用时,进行及时清理。
其他如ADO,UniDAC可能有自动清理的机制,但是很多时候需要你进行判断是否已经创建了相同的数据对象,存储在内存里

----------

5楼的,我的代码已经给出,不妨指出我哪里处理不当了?
难道要我扒开FireDAC组件,去帮助EMB取处理底层问题?
----------------------------------------------
樵夫的大马甲
作者:
男 jopher3 (樵夫的马六甲) ▲▲▲▲▲ -
普通会员
2016/11/21 17:13:53
14楼: 问题原因找到了!

是win10的问题! 同样的程序,换Win7下,就没问题!

哎~ 真是阴沟翻船了
----------------------------------------------
樵夫的大马甲
作者:
男 jopher3 (樵夫的马六甲) ▲▲▲▲▲ -
普通会员
2016/11/21 17:24:04
15楼: 妈的,被玩了好几个礼拜,一直泄漏泄漏
我靠,终于真相大白
----------------------------------------------
樵夫的大马甲
作者:
男 ywcljty (ywcljty) ★☆☆☆☆ -
普通会员
2016/11/21 17:41:17
16楼: 但原是WIN10问题,吓到老纳了,
----------------------------------------------
-
作者:
男 vmao (毛小毛) ★☆☆☆☆ -
盒子活跃会员
2016/11/21 17:46:09
17楼: Win10什么问题?Win10没有办法避免么?
----------------------------------------------
-
作者:
男 ghs_79 (ghs) ★☆☆☆☆ -
盒子活跃会员
2016/11/21 17:48:15
17楼: Win10不如Win7,我的程序与Wince通信,在Win7下就很正常,但Win10就经常出问题。
没办法就安装Win7虚拟机用。
----------------------------------------------
Delphi爱好者。
作者:
男 delphiilove (乌羽玉) ★☆☆☆☆ -
普通会员
2016/11/21 18:00:12
18楼: 好好好,这个帖子好。FireDAC 你委屈了。
----------------------------------------------
-
作者:
男 wang_80919 (Flying Wang) ★☆☆☆☆ -
普通会员
2016/11/21 18:02:27
19楼: WIN10 下 泄露,也算 EMB 的错误才对。
不然我们怎么办?
难道叫客户扔了WIN10?
客户不给钱!
----------------------------------------------
(C)(P)Flying Wang
作者:
男 pp0123 (pp0123) ★☆☆☆☆ -
普通会员
2016/11/21 18:54:45
20楼: 两点题外话:

数据库引擎大多内置 Thread 处理,没必要的话别要扣上线程处理。不竟实体运作上硬盘出来的也要经过是单线程。

Query 等东西最好在程序开关处理一次就好。因为 Create 一次会触动很多内部神经,系统要调拨资源相当,不遇上臭虫也有速度上的问题。对程序亳无好处。
----------------------------------------------
-
作者:
男 sqlnew (sqlnew) ★☆☆☆☆ -
盒子活跃会员
2016/11/21 19:40:16
21楼: (樵夫的马六甲):
能说下在win10是什么具体细节问题吗,应该如何避免,
可以谈下吗?
谢谢
----------------------------------------------
-
作者:
男 jopher3 (樵夫的马六甲) ▲▲▲▲▲ -
普通会员
2016/11/21 20:21:34
22楼: 有可能是我的windows 10不是原版纯净版的导致
我的是购买联想Thinkpad时安装的windows7,后来升级到win10的
可能是升级处理不到位,不如直接安装完整版的win10来得到位。

感想是这次亏大了,浪费了好些时间精力!
当然,好处也有,就是逼着自己查阅各种资料、尝试各种方法、不断优化系统。通过这样一折腾,相信系统更加稳固可靠。
----------------------------------------------
樵夫的大马甲
作者:
男 zzh2002 (鳄鱼) ★☆☆☆☆ -
普通会员
2016/11/21 21:23:12
23楼: xe8后的 FIREDAC一直存在一个问题,就是使用FDTABLE和FDQUERY通过APPEND或INSERT插入ID为自增长的数据集时,会报错,提示需为ID赋值。

而XE8及以前的版本没有此问题,UNIDAC也无此问题。

例:

TEST表中有ID字段,自增长 

fdquery1.sql.add('select * from Test');
fdquery.append;
fdquery.filedbyname('name').asstring:='Tom';
fdquery.post;

出错
----------------------------------------------
DELPHI编程爱好者
作者:
男 jopher3 (樵夫的马六甲) ▲▲▲▲▲ -
普通会员
2016/11/21 21:46:38
24楼: 刚才试了一下,windows10里的虚拟机(win server 2008)一样也是泄漏,估计是宿主为win10的原因。 我的估计,假如单独的win server 2008,应该不会泄漏。 明天试试
----------------------------------------------
樵夫的大马甲
作者:
男 wang_80919 (Flying Wang) ★☆☆☆☆ -
普通会员
2016/11/22 7:50:27
25楼: 说 EMB 质量差,结果有 BUG 不提交。鬼才给你改。
有些人,连 EMB 的账号都没有。
----------------------------------------------
(C)(P)Flying Wang
作者:
男 dolang (dolang) ★☆☆☆☆ -
普通会员
2016/11/22 9:11:43
26楼: 楼主,我怀疑是你使用的方式不正确。

在你的线程里的FDConn变量是全局变量还是局部变量?
这个FDConn最好是每次用完后就释放,使用前再创建,可以配合连接池。

看看官方的多线程介绍:
http://docwiki.embarcadero.com/RADStudio/Seattle/en/Multithreading_(FireDAC)

procedure TDBThread.Execute;
var
  oConn: TFDConnection;
  oPrc: TFDQuery;
begin
  FreeOnTerminate := False;
  oConn := TFDConnection.Create(nil);
  oConn.ConnectionDefName := 'Oracle_Pooled'; // see next section
  oPrc := TFDStoredProc.Create(nil);
  oPrc.Connection := oConn;
  try
    oConn.Connected := True;
    oPrc.StoredProcName := 'MY_LONG_RUNNING_PROC';
    oPrc.ExecProc;
  finally
    oPrc.Free;
    oConn.Free;
  end;
end;
----------------------------------------------
-
作者:
男 blk705 (凡人) ▲▲▲▲△ -
普通会员
2016/11/22 9:23:48
27楼: 回26楼,如果我记得没错,FireDAC的Connection是需要释放,FIREDAC的connection不同于UniDAC,DOA等机制。



顺便关注一下我的招聘帖子

http://bbs.2ccc.com/topic.asp?topicid=519745


----------------------------------------------
-
作者:
男 dolang (dolang) ★☆☆☆☆ -
普通会员
2016/11/22 9:59:33
28楼: 回27楼,你说的对,在多线程模式下是要每次使用时创建,用完后要释放的。
----------------------------------------------
-
作者:
男 jopher3 (樵夫的马六甲) ▲▲▲▲▲ -
普通会员
2016/11/22 11:53:07
29楼: 26,27楼: FDConnection可以复用的,这样可以实现有效的对象池,提高运行效率。

早上再度测试了,原因找到了: 是Windows版本、SQL Server2000、FireDAC三角恋没处理好关系导致。 现在专门为MSSQL的Link对象加一句:mssqllink.odbcdriver:='SQL Server'; 就全部搞定了!

谢谢各位同行参与讨论! 结帖。
----------------------------------------------
樵夫的大马甲
作者:
男 sqlnew (sqlnew) ★☆☆☆☆ -
盒子活跃会员
2016/11/22 12:02:31
30楼: 29楼:,原因是这个啊,这些问题还真是千奇百怪呀
谁能想到操作系统版本和数据库和中间件之间有冲突.
----------------------------------------------
-
作者:
男 jopher3 (樵夫的马六甲) ▲▲▲▲▲ -
普通会员
2016/11/22 12:20:06
31楼: 是啊,真是有些奇怪,要不好就彻底不好,那也好办,
但偏偏就是功能都正常,但内存泄漏,你说坑不吭人。

还有分页(读部分记录)、存储过程返回多个数据集等若干问题,似乎也与数据库的版本号有关...FireDAC还需全面的测试和完善——必须的。
----------------------------------------------
樵夫的大马甲
作者:
男 wang_80919 (Flying Wang) ★☆☆☆☆ -
普通会员
2016/11/22 12:54:58
32楼: 楼主啊,这还是 EMB 的 BUG 。你不设置,他干嘛要泄露?
他应该干脆点,发生错误才对。
----------------------------------------------
(C)(P)Flying Wang
作者:
男 wg961423 (麦子仲肥) ★☆☆☆☆ -
盒子活跃会员
2016/11/22 16:09:53
33楼: @jopher3,有没有试过在SQLServer里建链接服务器,链接服务器名设为IP地址,你用FireDAC来试试查询 select * from [xx.xx.xx.xx].xxx.dbo.table
----------------------------------------------
-
作者:
男 jopher3 (樵夫的马六甲) ▲▲▲▲▲ -
普通会员
2016/11/22 20:54:22
34楼: 对SQL 2000的支持,测出来的结果真是各种可能,坑死人:

windows server 2003,FireDAC, Sql 2000,不泄漏
windows server 2008,FireDAC, Sql 2000,泄漏
windows server 2012,FireDAC, Sql 2000,不泄漏
windows 7,FireDAC, Sql 2000,不泄漏
windows 10,FireDAC, Sql 2000,有些泄漏,有些不泄漏

哈哈,真像捅了马蜂窝
----------------------------------------------
樵夫的大马甲
作者:
男 shystep (shys) ★☆☆☆☆ -
普通会员
2016/11/22 21:01:31
35楼: 说明 win2003 win7 win8/2012 可靠些
----------------------------------------------
-
作者:
男 lsh341999 (虫子) ★☆☆☆☆ -
普通会员
2016/11/22 22:55:23
36楼: WIN10 是有点问题。以前用XE5/D2010开发的服务端(WIN2003 运行)与客户端在WIN10运行卡的要死。
但用DELPHI10重新修改编译过后又恢复正常了
原因嘛到现在也没找到,也懒得找了。
----------------------------------------------
就怕想不到,没有做不到的
作者:
男 zhangshelly (雪莱) ★☆☆☆☆ -
盒子活跃会员
2016/11/23 8:30:58
37楼: 顶楼上的,我的笔记本CPU是ES版I7,装了win10 时不时蓝屏,win7就没问题,win10稳定性还是有点怀疑
----------------------------------------------
-
作者:
男 wang_80919 (Flying Wang) ★☆☆☆☆ -
普通会员
2016/11/23 9:04:07
38楼: 楼上,你是 QS 版 修订 C0 以上的版本吗?
不是的话,据说CPU 内部可能有 BUG。
----------------------------------------------
(C)(P)Flying Wang
作者:
男 ccxpts (渔夫) ★☆☆☆☆ -
普通会员
2016/11/23 20:41:30
39楼: 樵夫:
  我是用win2008+datasnap+firedac,用10.1编译,运行几个月了正常没死机
----------------------------------------------
-
作者:
男 datm (dATM) ★☆☆☆☆ -
盒子活跃会员
2016/11/25 17:48:20
40楼: 39楼:
泄漏和死机没有直接关系,
如果没有不停的Create,Free 我个人都懒得管它有没有泄漏
----------------------------------------------
-
作者:
男 delphiilove (乌羽玉) ★☆☆☆☆ -
普通会员
2016/12/8 15:55:17
41楼: 这个帖子是不是该删除了,或者 把题目改了,给FireDAC 正名啊。
----------------------------------------------
-
作者:
男 hawke2e (hawke2e) ★☆☆☆☆ -
普通会员
2016/12/8 18:07:34
42楼: 向楼主致敬!!!
话说你不用DELPHI做服务端就不用这么麻烦 哈哈
----------------------------------------------
软件是什么,相信很多人都说不清。
信息
登陆以后才能回复
Copyright © 2CCC.Com 盒子论坛 v3.0.1 版权所有 页面执行218.75毫秒 RSS