Log On
Embarcadero Home
Watch, Follow, &
Connect with Us
Share This
QualityCentral
Communities
Articles
Blogs
Resources
Downloads
Help
QualityCentral
Delphi-BCB
Database
ADO
Azure
Blackfish SQL
CAB File
Config Maintenance
Core VCL
Data Access Controls
Data Aware Controls
Data Dictionary
Data Explorer
Data module
Database Tools
DataSnap
DBExpress
dbExpressCore
Debug Layer
Decision Cube Controls
Drivers
Environmental
Fields Editor
Form Wizard
Int'l Lang Driver
Performance
Remote Data Module
Sessions
Super Join
System Level Info
TField
TParams
You are not logged in.
Help
Print
Public Report
Report From:
Delphi-BCB/Database/dbExpressCore
[ Add a report in this area ]
Report #:
57849
Status:
Open
No code to free or close ParameterRowHandle in TDBXDynalinkCommand.CreateParameterRow cause memory leak
Project:
Delphi
Build #:
11.0.2902.10471
Version:
11.1
Submitted By:
Chee Yang Chau
Report Type:
Minor failure / Design problem
Date Reported:
2/4/2008 5:28:45 PM
Severity:
Commonly encountered problem
Last Updated:
3/20/2012 2:24:39 AM
Platform:
All platforms
Internal Tracking #:
258300
Resolution:
None
(Resolution Comments)
Resolved in Build:
:
None
Duplicate of:
None
Voting and Rating
Overall Rating:
No Ratings Yet
0.00 out of 5
Total Votes:
None
Description
A method in unit DBXDynalink.pas may cause serious memory leak in massive database operation using DBX4 drivers:
function TDBXDynalinkCommand.CreateParameterRow: TDBXRow;
var
ParameterRowHandle: TDBXRowHandle;
begin
if FCommandHandle = nil then
Open;
CheckResult(FMethodTable.FDBXCommand_CreateParameterRow(FCommandHandle, ParameterRowHandle));
Result := TDBXDynalinkRow.Create(FDBXContext, FMethodTable, ParameterRowHandle);
end;
The ParameterRowHandle is pass to TDBXDynalinkRow instance but TDBXDynalinkRow class didn't free the ParameterRowHandle.
I have used AQTime to do an allocation profile and found the leakage happens there.
This problem can't use FastMM or ReportMemoryLeaksOnShutdown to show the leakage as it occurs in the DBX4 dll files. If possible, you should compile the DBX4 dll files with "Include TD32 debug info" and include the DBX4 dll file to AQTime module.
Steps to Reproduce:
1. Open New VCL Application
2. Create TSQLConnection instance
3. Create TSQLDataSet instance
4. setup the connection to a database
5. Use the TSQLDataSet to query a table for 10000 times
e.g.:
for i := 1 to 10000 do begin
SQLDataSet1.Open;
SQLDataSet1.Close;
end;
6. Build both test application and DBX4 library for AQTime profiling. (e.g. include TD32 debug info, Stack Frames On)
7. Use Allocation Profiler in AQTime to run the application.
8. You will see lot of memory leaks.
Workarounds
Extract files in QC57849.ZIP and include in your project files will solve the leakage
Attachment
QC57849.zip
Comments
Boris Damianov at 10/20/2008 2:20:45 AM
-
Hello
I have tryed the workaround but the following error occur:
---------------------------
Debugger Exception Notification
---------------------------
Project DBXTest.exe raised exception class EAccessViolation with message 'Access violation at address 00CCDA6C in module 'dbxmss30.dll'. Read of address 00D101C0'.
---------------------------
Break Continue Help
---------------------------
Any suggestions please.
Chee Yang Chau at 1/18/2009 11:34:30 PM
-
I encounter the memory leak in my own DBX 4 dynalink driver written for Firebird database. For MS SQL server, you don't need this patch.
I am not sure how dbxmss30.dll manage the parameter row. For my case, I do need the FDBXBase_Close to be invoke some where in order to free the object I created for parameter row.
Chee Yang Chau at 9/9/2009 1:08:47 AM
-
I have found a workaround solution without relying on FDBXBase_Close to free parameter_row instance.
When DBXCommand_CreateParameterRow is invoke, I keep a reference of the Parameters to a list. When DBXCommand instance is close, the Parameters instance will be released:
function DBXCommand_CreateParameterRow(Handle: TDBXCommandHandle; out
Parameters: TDBXRowHandle): TDBXErrorCode; stdcall;
begin
Parameters := nil;
Result := IDBXCommand(Handle).CreateParameterRow(Parameters);
end;
function TDBXCommand_Firebird.Close: TDBXErrorCode;
var i: integer;
o: TDBXRowHandle;
begin
if Assigned(FDSQL) then begin
FDSQL.Close(StatusVector);
if not StatusVector.CheckResult(Result, TDBXErrorCodes.VendorError) then Exit;
end;
for i := 0 to GetParameterRows.Count - 1 do begin
o := GetParameterRows[i];
IDBXBase(o).Close;
IDBXBase(o) := nil;
end;
Result := TDBXErrorCodes.None;
end;
function TDBXCommand_Firebird.CreateParameterRow(out aRow: TDBXRowHandle):
TDBXErrorCode;
var M: IMetaDataProvider;
o: IDBXBase;
begin
M := TMetaDataProvider_Firebird.Create(FDSQL.o_SQLDA);
o := TDBXRow_Firebird.Create(FConnection, FDBHandle, M, FDSQL, (FConnection as IDBXConnection_Firebird).TrimChar);
IDBXBase(aRow) := o;
GetParameterRows.Add(aRow);
Result := TDBXErrorCodes.None;
end;
View Your Reports
Search
Server Response from: ETNACODE01
Developer Tools
Blackfish SQL
C++Builder
Delphi
FireMonkey
Prism
InterBase
JBuilder
J Optimizer
HTML5 Builder
3rdRail & TurboRuby
Database Tools
Change Manager
DBArtisan
DB Optimizer
ER/Studio
Performance Center
Rapid SQL
Technical Articles
Tutorials
White Papers
Press Releases
Newsletters
Add Content (GetPublished)
Audio
Audio & Video
Video
Bugs & Suggestions (QualityCentral)
Discussion Forums
Examples (CodeCentral)
Tags
Technology Partners
Downloads
Free Trials
Registered User Downloads
Beta Programs
Add Content (GetPublished)
Articles
Blogs
Bugs & Suggestions (QualityCentral)
Discussion Forums
Examples (CodeCentral)
Member Services
About
Connect with Us