Apparently, I don’t understand how constructors work.
When my application starts, it automatically or when needed executes my procedure that loads all resources – mostly images.
procedure Load;
begin
AppPath := GetAppPath;
INI := TInIFile.Create(AppPath + '\Config.ini');
INI.WriteBool('Application', 'Running', True);
ResPath := AppPath + '\Resources';
Top := TPicture.Create;
TopRight := TPicture.Create;
Left := TPicture.Create;
Right := TPicture.Create;
BottomLeft := TPicture.Create;
Bottom := TPicture.Create;
BottomRight := TPicture.Create;
...
//Load the pictures ...LoadFromFile(Skin.ReadString('Skin', ..., ...));
While I was using this application it started to lag a bit, but the OS started to freeze and lag too. I was shocked when I saw my program in Task Manager:

If I’m right, the application used 600 megs of RAM with page file included. My system has only 1 GB of RAM, so it’s no wonder the OS and almost every program started to lag due the page file usage.
Turned out it was that same procedure that loaded the resources every time I did something. I fixed it with adding a boolean to unit and the procedure canceled when it was set to true (means the resources are loaded).
Loaded: Boolean;
...
if Loaded = False then Load;
I’m not understanding why I had to make that change at all. Why did the constructor allocate memory for already-created objects in the first place?
Constructors only allocate memory when the object doesn’t already exist. If the constructor is called on an existing object, then that object is constructed; a new one is not allocated. (What you decide to do inside the constructor is another matter. Those instructions might allocate more memory in addition to whatever the
InstanceSizefunction returns for the class.)Your code doesn’t show any constructors being called on existing objects, though. You’re calling constructors on classes, and that allocates a new instance of each class. For example, you construct an INI-file object:
That calls the constructor on
TIniFile. It allocates a newTIniFileinstance and initializes it. Once that is finished, a reference to that new object is stored in theINIvariable. Important to realize is that ifINIalready held a reference to some other object, that reference is discarded and the new one is stored inINIinstead. You’re not calling theTIniFileconstructor on the object that’s already referenced byINI. That object is completely independent of the new one being created.The
INIvariable isn’t aTIniFileobject. It’s a reference to an object.You are apparently calling your
Loadfunction multiple times. Each time you call it, you re-run all the object constructors you ran before. You have a memory leak because each time you construct a new set of objects, you store references to them in the same variables you already stored the previous object references in. The previous values are discarded, and there’s no way to get them back, so there’s no way to free them. The way to solve this is as you’ve shown: Make sure you only initialize your program once by keeping track of whether you’ve already loaded.