Page 1 of 1

Posted: 01.01.2009, 01:22
by TheEdge
Hi Mark,

Nice one!! Looks like the 557 change did the trick as I see no issues in my simple test harness and my application seems to be behaving itself after doing some initial testing.

However.... :-) FastMM did throw up some memory leaks. This was from a simple connection no data modification and shut down of my application. You may want to peruse the attached and see if there is anything in there that does need fixing.

--D

Posted: 12.02.2009, 03:34
by skydvrz
I am having the same problem as TheEdge on build 584. Everything works fine when using MySQL, but on application shut down I am missing close to a megabyte. I can provide EurekaLog dumps of the memory leaks, but I'd prefer to not post them publicly.

I am running D2007 here. Let me know if you want the EurekaLog dump. Its ASCII text, or you can load it in their reader if you have it.

Thanks for a great product!

Kevin G. McCoy

Posted: 12.02.2009, 22:35
by mdaems
Well, let me admit, I have no idea about how to use these logs. I'm kind of a delphi/fpc beginner.
I really need some people who can really help me killing these memory leaks.
From what I tried in the past (part of?) this memory leak seems to come from the destroy of the connection that doesn't happen because there's a reference count on the metadata object that's not becoming zero when the connection is freed.

Mark

Posted: 13.02.2009, 02:58
by skydvrz
EurekaLog memory leak dumps show a stack trace, source code line number, leak count and amount of memory leaked for each unfreed memory block it finds.

If you know the original source fairly well (ZeosLib), you can use the dump as a roadmap to find the leak and redesign the code to not do that anymore :-)

I'd do it, but I have 3 large projects in the queue right now and don't have any free time.

If you look at the attached log, you'll see my code (cwoacp.exe and cwoacp.dpr) in the bottom of each trace of a leaked block of memory. As you move up in the stack trace you'll see functions calling functions, calling functions until you get to a Zeos function. The numbers at the far right are the line numbers in the source code files. The functions at the very top of each trace are usually low level system memory allocation calls. The culprit is usually somewhere in the middle of each stack trace. Look at the highest Zeos function in each leak stack trace on the line number indicated to find the wayward memory allocation.

It can also be a bad destructor that fails to free legitimately allocated memory. With the stack trace you can see exactly what isn't being freed and can redesign the destructor or finalization functions to deal with each leak.

The size of the leak and the number of individual leak instances appear as a header above each leak trace.

The biggest one is the leak in the class TZMySQLDriver.GetTokenizer on line 231 of ZDbcMySql.pas. It gobbled up 826,256 bytes on my machine.

My guess is that TZAbstractDriver should free the Tokenizer in its destructor, if it is non-nil. I could be wrong, since I spent about 2 minutes looking at it.

I think there is a free demo of EurekaLog that you can download. It integrates with your IDE and is a very powerful debug tool for problems just like this.

I hope this helps!

Best regards,

Kevin G. McCoy

Posted: 13.02.2009, 08:55
by mdaems
skydvrz,

I already had an idea what these dumps contain. So my main problem is the lack of expertise in tracing the problem down to the place where the memory should be freed but isn't...
I found out this has to do with freeing in destructors, but also with reference counting of interfaces. As long as the reference count of an interfaced object isn't zero the destroy of the object does not happen. Then the problem is to find out where exactly the different objects in the program are referenced exactly and find out which one isn't destroyed...

Your conclusion about freeing the tokenizer in the TZAbstractDriver destructor seems right when looking at it quickly. Did you try that? It should be an easy thing to test and solves 82% of your memory leak. I could add the destruction anyway but then the fix would be unverified.

So if you could add the needed line of code and do the dump again, I would :loveit: .

Posted: 13.02.2009, 19:20
by skydvrz
mdaems wrote:skydvrz,
Your conclusion about freeing the tokenizer in the TZAbstractDriver destructor seems right when looking at it quickly. Did you try that?
mdaems

I just played with it for a couple hours and it is more complex than I thought. If you have any TZAbstractRODatasets descendants in your app, the RebuildAll method starts creating new tokenizers for them.

One or more of the Tokenizers are not being freed at shutdown. I couldn't quickly figure out a way to free a Tokenizer inside RebuildAll without breaking something.

It looks to me like tokenizers should be freed after you are done using them in RebuildAll, but I haven't studied it long enough to have an informed opinion.

I really have to get back to work - sorry I can't be offer more time right now since I am completely buried in work.

I"d would be happy to help you test a new release, since I can consistently find memory leaks.

Best regards,

Kevin G. McCoy

Posted: 14.02.2009, 00:53
by mdaems
Thanks Kevin. I'm trying to debug it using FPC. (BTW : there's the heaptrace utility in FPC. Does almost the same)

It really seams like some resultset metadata objects are not destroyed. Probably the associated Tokenizer will stay in memory as well.

Mark