Form.Free doesn't free all system resources?
Posted on 2005-05-11
I am debbuging a strange case: A program that silently open and close some TForms without user input is giving me strange behaviours: After some TForm.create and the corresponding Form.Free, I get a "Canvas does not allow drawing" error on the Form.Create line.
A) Only one TForm is created at each moment, it is not nested or similar, so in theory, only one Form is alive.
B) I put this line inside a try except, and in the case it fails, it is tried a second time, and this time the error changes to "Out of system resources", so my gues is that I need to force some kind of garbage collection or similar. Memory usage of the proccess is not higher than when it started, but Windows proccess manager is very pethetic in the information it shows: No mention to system resources anywhere.
C) After some investigation, I pin pointed something strange that minimised the frecuency of those strange errors, and that can be a valuable clue: I had a object created inside the form that needed to reference the canvas of a TImage on the form, so it used a TCanvas varialbe that, on creation, was defined in the fasnion "Canvas:= Sender.Image.Canvas" so I had to pointers to the same canvas. The error was on some cases arraising here, so I changed it so only one pointer exists (Canvas is now a property that, on get it returns "Sender.Image.Canvas" so no copy of the canvas pointer is made).
D) Point C doesn't cause any problem is used by a human user (opening and closing the same Forms but using mouse clicks and closin using X buton) even if the user open and close more forms (by far) that the automatic proccess... so it is not a problem with the amount of TForms that have been opened and closed, it has to be a different between opening and closing programatically or manually.
E) In case it is a problem of garbage collection not being fired, I make a cleaun up each time I am going to open a form with this code:
if Win32Platform = VER_PLATFORM_WIN32_NT then
SetProcessWorkingSetSize(GetCurrentProcess, $FFFFFFFF, $FFFFFFFF);
So here I get lost in a sea of posibilities, none of witch really convince me... my bets goes to those posibilities:
1.- Creating, Showing and then Freeing a TCanvas or TForms from code need some kind of special free or similar that I am not aware of.
2.- FreeAndNil(Form) is not equivalent to closing it by mouse, may be the application is not aware of the freeing and keeps resources allocated in some how.
3.- I have some kind of "resource leak" in my code... I have tested it and I don't have any significant memory leaks, as after 10 or 20 create/free of TForms, the memory usage remains as when it started the job. Using a better proccess manager could help me in that point... I will be cheking while you read this!
4.- I deserve this because what I did during previous lifes ;)
Any suggestion will be tested, never mind if it sounds not very credible, I would beglad to fix it even without knowing why it was happening to me!