My program never releases the memory back. Why?
Asked Answered
E

5

3

I have a MDI program. When It starts it takes 2-3MB of RAM. Then, in this program I create about 260 MDI child windows (each has a TStringGrid, a bitmap and some other controls) and display some data. The application needs about 500MB to load all those windows. If I close each MDI child manually, the application still uses 160MB of RAM. Why it doesn't return to few MB of RAM? Should I worry about this? 160MB it is A LOT for a system that has only 1GB or RAM!!

Note: I use the WORKING SET column in Task Manager to see RAM statistics. Maybe I need a better tool to read the RAM utilization. (Private Working Set is just a bit smaller than Working Set).

This is not a leak!
FastMM (set on aggressive) indicates no memory leak when I close the program. See my Answer post for additional evidence that it isn't a leak.

I release stuff
Many people told me that closing a child window only hides it. I know that. I use "Action:= caFree" to actually release the forms. Each form is responsible for releasing the controls it holds.

Answer
I have found that FastMM is responsible for this. See the answer I posted below.


Delphi 7, Win 7 32 bit
Similar posts:
Can memory be cleaned up?
When to call SetProcessWorkingSetSize? (Convincing the memory manager to release the memory)

Encouragement answered 16/12, 2010 at 18:11 Comment(15)
It is impossible to answer this question as it stands.Liebman
How de you know your application is still using 160MB or RAM???Viscous
Hi Andreas. Please let me know if you need more data.Whisenant
@Viscous - I just updated my original postWhisenant
possible duplicate of Why doesn't my program's memory usage return to normal after I free memory?Prudi
@Altair As a simple test, why don't you create an empty app. Add a button whose OnClick event allocates the sort of memory that your real app does by calling GetMem. Make sure that you deallocate the memory in the same event handler that allocates it. How does it perform compared to your real app.Deraign
a) working set <> heap allocation b) task manager displays instantaneous values, not a statisticsEspecial
@Rob Kennedy - Hi. Salvador speaks about few MB of 'wasted' memory. In my case there are 160MB or unreleased RAM!!!Whisenant
@Altar If you have the code, surely you can work out if you are freeing the memory or not. FastMM is rock solid. Perhaps you have a problem, perhaps you don't, but FastMM won't be an issue. Do you know how the memory in question is being allocated? If so then you can check that it is being deallocated. But don't worry about how FastMM optimises in the background.Deraign
@David. Yes. The memory is properly released. But I still don't see how holding those 160MB of RAM can be good for the system. What happens if I open more files and after I release them, the memory 'unreleased' by FastMM is 800MB instead of 160MB? Maybe there is a way to 'purge' this RAM back?Whisenant
@Altar - Just to be sure files are closing when you expect them, run a utility like OpenedFilesView. While there, you can also have a look at other utilities like HeapMemView.Sprit
Hi Sertac. Thanks for pointing to those tools. HeapMemView is not very useful. However, GdiView (same web site) shows that I have 230 resources taken before loading my files. After loading the files I have thousand. After releasing the files, it returns 230 (actually it returns to 260 instead of 230, but it is close enough). If I open only one file and close it immediately, it returns to the previous value (precisely).Whisenant
@Altar - If files are closed and yet you see file data in heap memory, I think, that would mean the memory manager is not releasing the memory.Sprit
@Sertac - Forget about the files. I updated my post to show that this is not relevant. Plus I have found this is happening because FastMM not because of open files. Please see my post again (updated).Whisenant
@Altar - My comment does not say it is happening because of open files, on the contrary.. Plus, what files? I don't see a single file in the question! <g>Sprit
W
4

Answer:

I just removed FastMM from my project and the program returned to few MB after freeing all those child windows. Many may argue that this is not a misbehavior and that FastMM is doing this in order to do some kind of kinky memory optimizations. They may be true. However, it may be good for MY application but it may not be good of other running applications.

So, at least we know who causes this. I worried to a whole day that may program is leaking RAM like an old bucket. I am relieved now.

UPDATE:

To confirm that this behavior is generated by FastMM (as suggested by Barry Kelly) I created a second program that allocated A LOT of RAM. As soon as Windows ran out of RAM, my program memory utilization returned to its original value.
(Note: I am not saying there is a bug in FastMM!)

My program is not leaking. Problem solved.

Whisenant answered 17/12, 2010 at 11:58 Comment(0)
L
7

Task Manager is not the right tool to detect memory leaks. Delphi allocates large blocks of memory and keeps them later for future use, so certain increase in allocated memory is expected even after you release all resources. Any other results (and more detailed answers) can be obtained only by using specialize memory analysis tools. AQTime is the first that comes to mind, or if you can find old but useful MemProof, it would help you a lot (MemProof is free and for memory analysis it's more handy than AQTime).

Largo answered 16/12, 2010 at 18:22 Comment(3)
> so certain increase in allocated memory is expected even after you release all resources - - - - I know this. But I didn't expected such large quantities. I will try MemProof. Edit: Actually if it keeps about 1MB of RAM for each recently close window, then it makes sense.Whisenant
If you minimize your program, does the memory usage of your application suddenly drop? Then you are basing your conclusion on the wrong statistics.Piccaninny
@Lars-I am familiar with this behavior (seems to be prese4nt since Win XP). It was the first thing to try :) Unfortunately it doesn't happen with this application.Whisenant
R
4

It is very well possible that FastMM does not show memory leaks upon application termination (for instance because all objects are TComponents that are owned, and the ownser frees them).
But in the mean time, while running those components can still be around, and not freed soon enough.

Did you use the FastMM unit that shows a form with the current memory usage?

< Edit >
This is the FastMMUsageTracker.pas in the directory ...\FastMM\Demos\Usage Tracker.
Use that unit, then call the ShowFastMMUsageTracker function in it. You can refresh that form every once in a while to see how your memory consumption grows. I have put a FastMMUsageTrackerProject sample on-line, including an update of FastMM4 that makes it easier to check and debug memory leaks:

  • the form in the FastMMUsageTracker unit is now resizable, and the controls in it anchor in the right way
  • there is a new FastMmBootstrapUnit unit making debugging specific memory leaks easier

Something I had at hand last week, was a 3rd party DLL, which was not written in Delphi.
The DLL had a memory leak using Windows GlobalAlloc calls, which are not tracked by FastMM.

NB: I'm about to post an update to FastMM on

--jeroen

Rodas answered 16/12, 2010 at 20:8 Comment(3)
>FastMM unit that shows a form with the current memory usage? - - - I am not aware about this unit. Maybe it is only for Delphi 2010? Can you hint me with some name so I can do a google search about it?Whisenant
People are saying that FastMM cannot fail: #4478436 I think I agree with them.Whisenant
@Jeroen-Thanks. I will used that unit right away. I have checked my code and 3rd party libraries against GlobalAlloc. It is not used in my project.Whisenant
W
4

Answer:

I just removed FastMM from my project and the program returned to few MB after freeing all those child windows. Many may argue that this is not a misbehavior and that FastMM is doing this in order to do some kind of kinky memory optimizations. They may be true. However, it may be good for MY application but it may not be good of other running applications.

So, at least we know who causes this. I worried to a whole day that may program is leaking RAM like an old bucket. I am relieved now.

UPDATE:

To confirm that this behavior is generated by FastMM (as suggested by Barry Kelly) I created a second program that allocated A LOT of RAM. As soon as Windows ran out of RAM, my program memory utilization returned to its original value.
(Note: I am not saying there is a bug in FastMM!)

My program is not leaking. Problem solved.

Whisenant answered 17/12, 2010 at 11:58 Comment(0)
R
0

The main limitation of FastMM's memory leak tracing is that it can only run when you shut down the program. It could be that you're still holding references to objects or other data that gets cleaned up when you shut down the program, but stays around until then.

For example, when you close the MDI child windows, do you call Free or Release on them, or just make them disappear? If they're hidden but not freed, they'll still be in memory.

Roderic answered 16/12, 2010 at 18:24 Comment(5)
I FREE the forms. If the child forms will be only hidden then the amount of RAM will not drop from 500 to 160MB.Whisenant
Are you sure the forms are to only objects holding references to the data they are displaying? It may not be the forms that are failing to release the memory.Reorganization
@codeelegance. Yes. Plus FastMM will jump instantly at me if I fail to release some objects (leak memory).Whisenant
As Mason pointed out FastMM will only complain when the program terminates. You asked about memory usage while it is still running. So long as the objects have been released before termination FastMM won't see a problem.Reorganization
>So long as the objects have been released before termination FastMM won't see a problem - - - Agree with you!! This means that (since my FastMM is not complaining) I don't leak memory! This is good. The question is: is it healthy for FastMM NOT to release the memory???? Maybe other programs need that memory badly.Whisenant
E
0

If you close an MDI form it is not freed automatically. Use Action = caFree (google for that) to make sure the form is also freed.

Ediva answered 17/12, 2010 at 7:48 Comment(1)
I free the forms (see previous answers).Whisenant

© 2022 - 2024 — McMap. All rights reserved.