使用FireDAC定义连接时出现内存泄漏问题求助
问题分析与修复方案
1. 明确的内存泄漏:未释放TStringList实例
你在DataModuleCreate中创建了oParams : TStringList,但没有在代码中释放它,这是直接导致内存泄漏的原因。修改代码时要确保所有手动创建的对象都在finally块中释放,避免异常场景下的泄漏:
修正后的DataModuleCreate代码:
procedure TDataModule2.DataModuleCreate(Sender: TObject); var oParams : TStringList; cdir, fname : string; fs : TFileStream; sr : tStreamReader; begin cdir := GetCurrentDir; fname := 'conn.ini'; oParams := TStringList.Create; try try fs := TFileStream.Create(cdir+TPath.DirectorySeparatorChar+fname, fmOpenRead); try sr := tStreamReader.Create(fs, TEncoding.UTF8); try while not sr.EndOfStream do oParams.Add(sr.ReadLine); FDManager1.AddConnectionDef('MySQL_pooled', 'MySQL', oParams); finally sr.Free; end; finally fs.Free; end; except on E: EFileStreamError do ShowMessage('文件未找到: '+e.Message); end; finally oParams.Free; // 确保TStringList始终被释放 end; end;
2. FireDAC连接资源未正确清理
除了上述对象泄漏,还需要确保程序退出时释放数据库连接资源:
- 在DataModule的销毁事件中添加连接清理逻辑:
procedure TDataModule2.DataModuleDestroy(Sender: TObject); begin // 先断开当前活跃连接 if FDConnection1.Connected then FDConnection1.Connected := False; // 清理连接池中的所有闲置连接 FDManager1.CloseConnections; end;
- 你的
conn.ini配置存在矛盾:设置了Pooled=false却又配置POOL_MaximumItems=100。如果不需要连接池,删除所有POOL_开头的配置项;如果需要池化,将Pooled=true,让FireDAC自动管理连接池生命周期。
3. 额外建议
- 确认FDManager的
AutoFreeConnections属性为True(默认值),该属性会在FDManager销毁时自动释放所有未关闭的连接。 - 确保DataModule的销毁顺序晚于所有使用它的窗体,避免窗体销毁时仍持有DataModule的连接引用。
内容的提问来源于stack exchange,提问作者Franz Andreani
相关产品推荐
相关产品推荐

