2

We are having trouble with a memory leak that happens only when the application is running (there is no FastMM report when we close the application).

We isolate the problem to a method that reads values from a database and instantiate objects from the result. (we are using DBXPress to database connection)

The class that do the database stuff implements an interface. Using a test application that does nothing else but run a thread reading values from the database (always the same values), the application in Delphi 7 do not leak. But in Delphi 2007 the memory used jumps really fast. It is the same code, same test application.

When you check the application with AQTime you can see the number of TStringList, TList, etc (all the objects the database class uses) growing and shrink - but checking the memory with ProExplorer and with Windows task manager, the Delphi 2007 version grows really fast.

Our only guess is that there is something different in the way Delphi 7 and Delphi 2007 deals with interface releasing. Does it make sense? Anyone had experienced something similar?

RRUZ
  • 134,889
  • 20
  • 356
  • 483
ronaldosantana
  • 5,112
  • 4
  • 22
  • 28
  • 3
    If FastMM doesn't report the leak, then there is no leak. Or if there is a leak, it's memory allocated with a different allocator, e.g. in a 3rd party DLL. – David Heffernan Mar 17 '11 at 00:47
  • Now that you've mentioned, the other thing different is that on Delphi 2007 we are using dbxINT30.dll It is like Delphi 7 version (or the DLL version on Delphi 7) for some reason know how to free the memory, etc - but with the Delphi 2007 version, it just keeps growing - when close, no leak report, but something is really wrong... – ronaldosantana Mar 17 '11 at 01:11
  • 3
    @david: FastMM will only report leaks that remain leaked at program end. If you leak memory during execution that is being somehow cleaned up before the program terminates then FastMM doesn't consider this a leak. I am surprised that someone with your experience does not know this. ;) – Deltics Mar 17 '11 at 01:12
  • 1
    @david, cont.: Example: a form that creates an owned component in response to some event when it should create one such component initially and re-use it in subsequent events. When the form is closed the "leaked" components get cleaned up because they are owned by the form. It's not a leak as far as FastMM leak detection is concerned, but it is never-the-less a leak in that form that could potentially end up crippling your app. – Deltics Mar 17 '11 at 01:14
  • Maybe in the new DLL, memory is directly allocated bypassing FastMM (see http://stackoverflow.com/questions/4477936/does-fastmm-detect-all-memory-leaks) – mjn Mar 17 '11 at 06:30
  • @Deltics: Touché! I do know that, but never consider it because I personally never use the Owner property to free objects that I create in code. Naturally I used it for streamed components, but I always write Create/Free pairs in Try/Finally blocks. So that sort of leak is simply not on my radar but I agree it could be an issue here. – David Heffernan Mar 17 '11 at 08:02
  • @David: The "Owner" mechanism is only *one* example. Any number of mechanisms may exist that provide incomplete memory management *during* execution but which do not result in a leak at process termination. – Deltics Mar 17 '11 at 20:40
  • @Deltics It's probably the main one in a Delphi program. What other mechanisms are you thinking off – David Heffernan Mar 17 '11 at 20:46
  • @David: I'm not talking about "proscribed" or standard mechanisms. We can make that software do whatever we like. The authors of the VCL provided an "Owner" mechanism for managing the lifetimes of certain objects with a specific relationship between each other. In our own code we have at our disposal an infinite variety of means for implementing similar things. THOSE are what I am referring to, not any specific implementation. VCL "Owner" is just ONE concrete example that I provided as an *illustration* of what I meant. I cannot know what similar mechanisms might be in the OP's own code. – Deltics Mar 17 '11 at 21:58
  • @David. cont: The point is simply that FastMM will only report specific types of memory leak, i.e. those that *remain* leaked at process termination. But there are other types of memory leak, leaks that are "plugged" BEFORE program termination, and FastMM will NOT help you find those. – Deltics Mar 17 '11 at 22:00
  • @Deltics Agreed. FastMM is still useful though! – David Heffernan Mar 17 '11 at 22:01
  • FastMM is useful when detecting leaks that FastMM can detect. For all other types of memory leak it is, by definition, use*LESS*. Give someone a hammer and it seems some people then start to see everything as a nail... ;) – Deltics Mar 18 '11 at 04:04

1 Answers1

3

Well... My 2 cents:

There is nothing diffent in the way delphi 2007 works with interfaces. But a long time ago i had a similar issue with interfaces, and i ended up not using the interface reference count at all. It does not work really well.

You did not post you source, but i guess your objects that implements the interface are inheriting from TInterfacedOject, am i right? If so, consider changing it to you own TInterfacedObject that will not implement the reference count methods. You will have to destroy your objects, instead of having delphi deal with them.

Another thing you might consider is to tell delphi you are no longer needing the interfaced object, by setting nil to the interfaced object you are not using.

But as everybody said on comments, if fastmm is not reporting a leak, them there are no leaks at all. The fact that the memory is growing fast do not indicate that your program are leaking. It only says that you are not pay attention on your objects as you wanted to.

You should use EurekaLog. It is a very good addon that reports memory leaks and their callstack.

Also, take a look at this Question

Community
  • 1
  • 1
Rafael Colucci
  • 6,018
  • 4
  • 52
  • 121
  • Regarding limitations of FastMM see http://stackoverflow.com/questions/4477936/does-fastmm-detect-all-memory-leaks – mjn Mar 17 '11 at 06:29
  • Hi @Rafael Colucci - you right about the TInterfacedObject. Thanks also for the link for the other question and the EurekaLog tip. – ronaldosantana Mar 17 '11 at 19:22