Mega Search
23.2 Million


Sign Up

Make a donation  
Memory leak when catching exceptions in XE2  
News Group: embarcadero.public.cppbuilder.language.cpp

Hi,

I have an application built with C++ Builder XE2 update 4 that is using the dbGo components (TADOQuery etc) to access a DB2 database.  The application appeared to be leaking memory whenever I tried to perform an insert using the TADOQuery->ExecSQL statement within a try/catch block and an exception was generated because of a primary key violation in the database.  I have spent quite a lot of time trying to determine whether the leak is caused by the TADOQuery component, DB2 OLEDB driver or something else 
entirely.  Eventually I decided that there must be something wrong with the exception handling mechanism and resorted to writing a very basic application (see below) to test this theory.  To my amazement, just throwing and catching an exception in a loop eats memory under C++ Builder XE2.

{code}
void __fastcall TForm1::Button1Click(TObject *Sender)
{
	while (1)
	{
		try
		{
			throw Exception("My Exception");
		}
		catch (Exception& E)
		{
			Label1->Caption = E.Message;
		}
	}
}
{code}

When viewing the memory usage of this test application with Windows task manager, the peak working set increases continuously and it will eventually crash with an out of memory error.  This same code does not leak memory when compiled with C++ Builder 6.  I have tried similar code using Delphi XE2 and it also runs without consuming memory.

Could this be a problem with Exception destructors in C++ Builder XE2?.  I have "Enable RTTI", "Enable exceptions" and "Destructor cleanup" set to true in the project C++ compilation options as per default.

Any help would be very much appreciated.

Vote for best question.
Score: 0  # Vote:  0
Date Posted: 4-Feb-2013, at 9:15 PM EST
From: Aaron Croad
 
Re: Memory leak when catching exceptions in XE2  
News Group: embarcadero.public.cppbuilder.language.cpp
> {quote:title=Remy Lebeau (TeamB) wrote:}{quote}
> Vladimir wrote:
> 
> > then your advice is misleading and excessively restrictive because
> > whenever one needs to modify caught exception object he has to
> > catch by non-const reference and it works just fine
> 
> Why would you modify a raised exception?
> 
> --
> Remy Lebeau (TeamB)

Hi all,

Thanks for the responses but they don't tell me why throwing and catching an exception leaks memory.  This is the case regardless of whether the exception is caught by const reference or not.
 
Cheers,
Aaron.

Vote for best answer.
Score: 0  # Vote:  0
Date Posted: 6-Feb-2013, at 3:24 PM EST
From: Aaron Croad
 
Re: Memory leak when catching exceptions in XE2  
News Group: embarcadero.public.cppbuilder.language.cpp
> {quote:title=Remy Lebeau (TeamB) wrote:}{quote}
> Aaron wrote:
> 
> > Thanks for the responses but they don't tell me why throwing and
> > catching an exception leaks memory.  This is the case regardless of
> > whether the exception is caught by const reference or not.
> 
> Using Windows Task Manager to track memory leaks is not accurate or reliable. 
>  All it can report is how much memory the process has allocated, not how 
> that memory is being used.  Just because the memory usage grows does NOT 
> always mean that memory is leaking.  For instance, the RTL's Memory Manager 
> caches freed memory for later reuse.  Task Manager does not know that.  If 
> you want to know what is really leaking, set the RTL's global System::ReportMemoryLeaksOnShutdown 
> variable to true, or install the full version of FastMM and enable its leak 
> reporting features, and then exit your app.  If it is not reporting any leaks, 
> then there are no leaks actually occuring.  A growth in memory usage without 
> leaks occuring usually means memory is being fragmented instead, causing 
> the MM to allocate more and more memory because it cannot reuse what it already 
> has in its cache.
> 
> --
> Remy Lebeau (TeamB)

Hi Remy,

Thanks for the advice regarding Windows task manager and memory fragmentation.  I have tried setting ReportMemoryLeaksOnShutdown and do not see any message dialog displayed when I close the application, which would suggest that there is no leak.  What I am failing to understand is why I see different behaviour between C++ Builder XE2 and either C++ Builder 6 or Delphi XE2.  I can image that there may have been changes in the memory manager between versions 6 and XE2 of C++ Builder but why the difference b
etween the same version of C++ Builder and Delphi?  Also, something seems terribly wrong if I can fragment memory and eventually run out just by throwing the same exception with the same constructor over and over again.  Surely the memory manager should be able to reallocate from its cache unless the size of the exception object is growing with each call.  I am not increasing the size of the exception message so what is going on?

Cheers,
Aaron.

Vote for best answer.
Score: 0  # Vote:  0
Date Posted: 6-Feb-2013, at 10:17 PM EST
From: Aaron Croad
 
Re: Memory leak when catching exceptions in XE2 [Edit]  
News Group: embarcadero.public.cppbuilder.language.cpp
> {quote:title=Remy Lebeau (TeamB) wrote:}{quote}
> Aaron wrote:
> 
> > catch (Exception& E)
> 
> Always catch exceptions by 'const' reference instead:
> 
> {code:cpp}
> catch (const Exception& E)
> {code}
> 
> --
> Remy Lebeau (TeamB)

Hi Remy,

I have modified my test application to catch by const reference and it makes no difference.  The memory leak still occurs.

Cheers,
Aaron.

Edited by: Aaron Croad on Feb 4, 2013 6:12 PM

Vote for best answer.
Score: 0  # Vote:  0
Date Posted: 4-Feb-2013, at 10:13 PM EST
From: Aaron Croad
 
Re: Memory leak when catching exceptions in XE2  
News Group: embarcadero.public.cppbuilder.language.cpp
> {quote:title=Alex Belo wrote:}{quote}
> Aaron Croad wrote:
> 
> > > Using Windows Task Manager to track memory leaks is not accurate or
> > > reliable.
> 
> IMHO TM is not so unreliable. If it shows massive increase of memory
> usage it usually indicates troubles in most cases.
> 
> > > Just because the
> > > memory usage grows does NOT always mean that memory is leaking.
> > > For instance, the RTL's Memory Manager caches freed memory for
> > > later reuse.
> 
> Yes, but FastMM returns big blocks to system AFAIK.
> 
> > > A growth in memory usage
> > > without leaks occuring usually means memory is being fragmented
> > > instead, causing the MM to allocate more and more memory because it
> > > cannot reuse what it already has in its cache.
> 
> Yes, but FastMM also does not tend to memory fragmentation, especially
> in such very simple test program.
> 
> > I have tried setting ReportMemoryLeaksOnShutdown and do not see any
> > message dialog displayed when I close the application
> 
> AFAIK Version of FastMM shipped with Studio detects only leaks in
> Pascal code, not in C++ code.
> 
> Try last madExcept: it has nice CB memory leak detector now.
> 
> > What I am failing to
> > understand is why I see different behaviour between C++ Builder XE2
> > and either C++ Builder 6
> 
> Old MM in BCB6 has much worse fragmentation. Looks as bug to me.
> 
> Anyway, if the same code works as expected in XE3 (could someone test
> it?) you have no option except buying this fix (XE3).
> 
> -- 
> Alex

Hi,

I would really appreciate it if someone was willing to verify my findings with C++ Builder XE2 or confirm whether or not the problem exists in XE3.  I have thought about upgrading to XE3 to get the 64-bit compiler but would like to know that it works first.

--
Aaron.

Vote for best answer.
Score: 0  # Vote:  0
Date Posted: 10-Feb-2013, at 5:38 PM EST
From: Aaron Croad
 
Re: Memory leak when catching exceptions in XE2  
News Group: embarcadero.public.cppbuilder.language.cpp
> {quote:title=Aaron Croad wrote:}{quote}
>
> I would really appreciate it if someone was willing to verify my findings with C++ Builder XE2 or confirm whether or not the problem exists in XE3.

I tested using XE 3 Update 2 and Process Explorer from Sysinternals and can see on ther "PErformance" tab that under "Physical Memory" the value for "WS Private" is constantly increasing over time by 4k. If I enable CodeGuard in debug mode no memory leak is reported, but the value "WS private" is still increasing.

Vote for best answer.
Score: 0  # Vote:  0
Date Posted: 11-Feb-2013, at 3:40 AM EST
From: Andreas Muchow
 
Re: Memory leak when catching exceptions in XE2  
News Group: embarcadero.public.cppbuilder.language.cpp
> {quote:title=Andreas Muchow wrote:}{quote}
> > {quote:title=Aaron Croad wrote:}{quote}
> >
> > I would really appreciate it if someone was willing to verify my findings with C++ Builder XE2 or confirm whether or not the problem exists in XE3.
> 
> I tested using XE 3 Update 2 and Process Explorer from Sysinternals and can see on ther "PErformance" tab that under "Physical Memory" the value for "WS Private" is constantly increasing over time by 4k. If I enable CodeGuard in debug mode no memory leak is reported, but the value "WS private" is still increasing.

Many thanks Andreas.  Does it eventually fail with an "Out of memory" error?

How do we go about getting this fixed?

--
Aaron.

Vote for best answer.
Score: 0  # Vote:  0
Date Posted: 11-Feb-2013, at 10:16 PM EST
From: Aaron Croad
 
Re: Memory leak when catching exceptions in XE2  
News Group: embarcadero.public.cppbuilder.language.cpp
> {quote:title=Aaron Croad wrote:}{quote}
>
> Does it eventually fail with an "Out of memory" error?

I didn't let the program run long enough, just waited for some MB to be leaked.

Vote for best answer.
Score: 0  # Vote:  0
Date Posted: 12-Feb-2013, at 5:10 AM EST
From: Andreas Muchow