3

"Application" is part of VCL, and thus is not thread-safe (likely in maintaining a non-thread-safe list of components it owns).

The project I'm working on has several instances where Application is set as Owner, and Self is not an option (class method). I would like to pass "nil" instead, given that the variable is freed at the end of this function.

Assuming someone forgets to free an Application-owned variable:

when the Application closes, the memory gets freed. But I also read that Windows keeps track of the memory assigned to each process. So, theoretically, if a nil-owned variable was not freed, Windows would release it when the Application / process are terminated.

What benefit, then, in setting the owner to Application as opposed to Nil?

The following question talks about responsibility of freeing nil-owned vars, but stops there:

What is the meaning of nil owner in component constructor

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
Khorkhe
  • 1,024
  • 1
  • 11
  • 26

1 Answers1

5

Whilst it is true that the system will release memory when the process terminates, leaks during execution are a potential problem. If a program performs repetitive actions, and leaks memory each time, then these leaks build up over time and eventually lead to out of memory conditions.

The same behaviour can be seen with components that are owned by the application singleton object. If they are not explicitly destroyed, then they are destroyed only when the application terminates. Again these leaks could build up over time, as the process executes.

The normal method for detecting leaks is to keep track of all allocations during execution, and then, as the final act of process termination, to check that all allocations have had matching deallocations. This functionality is offered by various tools, but in a Delphi context the FastMM memory manager is the most commonly used tool that offers this.

If you create a component that is owned by the application object, and don't explicitly destroy it, it won't show up as having been leaked when your leak checker executes. This is not desirable because you have true leaks that are not detected.

This argument leads to the conclusion that it would be preferable to have unowned components in the scenario you describe.

The flip side to this is that sometimes you create components that you wish to live as long as the application object, and it may be hard to find a good place in the code to destroy them explicitly. In that case, being owned by the application object is a good approach. That's exactly what the owner mechanism is designed for.

My rules of thumb here:

  1. If a component is created by the streaming system (i.e. A form), it will use the ownership mechanism to ensure correct lifetime management. You have nothing to do in code.
  2. If you create the component explicitly in code then it is best to follow the normal creation patterns and also explicitly destroy it in code. In that case, make the component be unowned.
  3. If you aren't easily able to find a good place to destroy the component, and you can tie its lifetime to another component (i.e. the application), pass that component as the owner.

Getting back to the question you asked. You asked for reasons why it is advantageous to use the application object as owner. As argued above, in many cases it is actually advantageous to have such components be unowned. But also there are times when it is advantageous to have the application object as owner.

In conclusion, there is no single hard rule to follow. You need to understand the implications of ownership, and then choose the appropriate owner for each component, which may vary form one situation to another.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • The FastMM not reporting is definitely something I've encountered, when components are owned by the Application. As for your 3rd point, that definitely makes sense, thanks. If you don't mind, i've edited the question to add a point initially forgotten – Khorkhe Apr 04 '20 at 08:16
  • FastMM won't report a leak for a component owned by the application because it will be destroyed at termination. But if its an object that your program creates repetitively then it is still a leak and can lead to out of memory. I tried to explain that in the answer. An object that is destroyed at termination instead of being destroyed when it is no longer used is still a leak, but one that classic leak detection tools don't detect. – David Heffernan Apr 04 '20 at 08:41
  • I rolled back your edit. That's a completely different question. Ask it as a new question. – David Heffernan Apr 04 '20 at 08:42