Recent

Author Topic: How to automatically free classes/objects?  (Read 10868 times)

aradeonas

  • Hero Member
  • *****
  • Posts: 824
How to automatically free classes/objects?
« on: March 01, 2016, 08:50:51 pm »
Subject say what I want and as discussed here there are couple of ways to do this and one of them is a custom garbage collector :
 
I want to know is there any better way in Lazarus or what should I do?
 
Regards,
Ara

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11453
  • FPC developer.
Re: How to automatically free classes/objects?
« Reply #1 on: March 01, 2016, 09:15:48 pm »
No. Basically that is it. Sven says he is studying on ARC (ref counted objects, manually decycled). If something comes up I usually add it to http://wiki.freepascal.org/garbage_collection

aradeonas

  • Hero Member
  • *****
  • Posts: 824
Re: How to automatically free classes/objects?
« Reply #2 on: March 01, 2016, 09:19:13 pm »
OK.
marcov what ways you think is best for now?

vfclists

  • Hero Member
  • *****
  • Posts: 1013
    • HowTos Considered Harmful?
Re: How to automatically free classes/objects?
« Reply #3 on: March 07, 2016, 07:41:38 am »
Subject say what I want and as discussed here there are couple of ways to do this and one of them is a custom garbage collector :
 
I want to know is there any better way in Lazarus or what should I do?
 
Regards,
Ara

I looked up some interesting options

http://stackoverflow.com/questions/415958/how-to-automatically-free-classes-objects 
http://stackoverflow.com/questions/398137/best-practice-to-do-nested-try-finally-statement?lq=1 
http://edn.embarcadero.com/article/28217
Lazarus 3.0/FPC 3.2.2

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11453
  • FPC developer.
Re: How to automatically free classes/objects?
« Reply #4 on: March 07, 2016, 09:19:52 am »
OK.
marcov what ways you think is best for now?

Come to terms with the fact that Object Pascal is not a garbage collected language.

Hacks like vfclists are mainly used in business code where there is often a fixed pattern (get objects from e.g. OPF, take decision, store to opf), where you can try to free some temporary objects, simplifying business code somewhat.

I never found much use for the constructs outside such scenarios, and even for those scenarios, I always thought they were overrated.
« Last Edit: March 07, 2016, 09:22:16 am by marcov »

vfclists

  • Hero Member
  • *****
  • Posts: 1013
    • HowTos Considered Harmful?
Re: How to automatically free classes/objects?
« Reply #5 on: March 07, 2016, 01:07:57 pm »
I am currently creating some controls at runtime, ie I am running arbitrary SQL queries and I need to create the fields to display them.

Currently when I load a new dataset with different fields I have to free the old controls and create new ones.

The controls are created as TControl.Create(AOwner) where AOwner is the form. If I create the controls as TControl.Create(ATabSheet) where ATabSheet is the parent they are placed on, will simply Destroying ATabSheet means all the controls will be freed as well?
Lazarus 3.0/FPC 3.2.2

Bart

  • Hero Member
  • *****
  • Posts: 5290
    • Bart en Mariska's Webstek
Re: How to automatically free classes/objects?
« Reply #6 on: March 07, 2016, 01:37:07 pm »
If I create the controls as TControl.Create(ATabSheet) where ATabSheet is the parent they are placed on, will simply Destroying ATabSheet means all the controls will be freed as well?

Yes, Owner frees it's Objects (or at least (s)he should).

Bart

vfclists

  • Hero Member
  • *****
  • Posts: 1013
    • HowTos Considered Harmful?
Re: How to automatically free classes/objects?
« Reply #7 on: March 07, 2016, 09:41:51 pm »

I also have this piece of code, they are all related anyway. This is a long one so please be gentle  :)

I have an TStringList which has the TFieldControl objects attached to it.

Code: Pascal  [Select][+][-]
  1.   TFieldControl= class(TObject)
  2.     fldLabel:TLabel;
  3.     fldControl: TWinControl;
  4.   end
;
     

Code: Pascal  [Select][+][-]
  1. begin
  2.   fL := TStringList.Create;
  3.   d := dS.Dataset;
  4.   d.GetFieldNames(fL);
  5.   // create fields
  6.   for i := 0 to fL.Count - 1 do
  7.   begin
  8.     if not Assigned(fL.Objects[i]) then
  9.     begin
  10.       fLd := d.FieldByName(fL[i]);
  11.       fLd.DisplayLabel := SetDisplayLabel(fLd.FieldName);
  12.       fL.Objects[i] := TFieldControl.Create;
  13.       TFieldControl(fL.Objects[i]).fLdLabel := TLabel.Create(nil);
  14.       TFieldControl(fL.Objects[i]).fLdLabel.Caption := fLd.DisplayLabel;
  15.  
  16.       case fLd.DataType of
  17.       ftString, ftSmallint, ftInteger, ftWord,
  18.    ftfLoat, ftCurrency, ftBCD, ftDate,  ftTime, ftDateTime,ftWideString,
  19.   ftLargeint,ftTimeStamp:
  20.         begin
  21.           e := TDBEdit.Create(pnlControls);
  22.           e.DataSource := dS;
  23.           e.DataField := fL[i];
  24.           e.Width := ctlLayoutEditWidth;
  25.           TFieldControl(fL.Objects[i]).fLdControl := e;
  26.         end;
  27.          ftMemo, ftFmtMemo, ftWideMemo:
  28.          begin
  29.            if not Assigned(sbControls) then
  30.              sbControls := TScrollBox.Create(pnlMemos);
  31.            m := TDBMemo.Create(pnlMemos);
  32.            m.DataSource := dS;
  33.            m.DataField := fL[i];
  34.            m.Parent := sbControls;
  35.            m.Align := alTop;
  36.            m.ScrollBars := ssAutoBoth;
  37.            m.Font.Name := 'Courier New';
  38.            TFieldControl(fL.Objects[i]).fLdControl := m;
  39.          end;
  40.          ftBoolean:
  41.          begin
  42.            c := TDBCheckBox.Create(pnlControls);
  43.            c.DataSource := dS;
  44.            c.DataField := fL[i];
  45.            c.Caption := fLd.DisplayLabel;
  46.            TFieldControl(fL.Objects[i]).fLdControl := c;
  47.          end;
  48.       end;
  49.  

fL is TStringList index on the fieldnames which have the TFieldObject attached to it.
What I want to confirm is this:

1. If I set the OwnsObjects property of fL and I free fL, the Objects will be freed;

2. Because Objects do not automatically free their fields, the TFieldControl objects will remain. even if the Objects are freed, unless I free the FieldControl objects themselves.

3. If I free the TFieldControl objects, the controls hold will still occupy memory, because TFieldControl is not a record, and fldLabel and fldControl are allocated on the heap. If they were assigned to other objects eg. SomeFieldControl := TFieldControl, SomeFieldControl will still be pointing to the controls even if the TFieldControl was freed.

4. If I set the TLabel and TControl properties of the TFieldControl to nil, without freeing the TLabel and TControl before, SomeFieldControl would be unaffected.

5. If  TFieldControl is created via a constructor and destructor freeing TFieldControl will not free fldLabel and fldControl if the destructor is not called or does not explicitly Free fldLabel and fldControl

6. if pnlControls and pnlMemo are freed all the controls on them will also be freed.

Pont 3 looks questionable, ie freeing TFieldControl will probably nil the memory pointers allocated to fldLabel and fldControl, making SomeFieldControl invalid.

If I did SomeFieldControl.Assign(FieldControl), will SomeFieldControl still be valid  if FieldControl was freed without freeing fldLabel and fldControl because SomeField control uses its own storage for its pointers
Lazarus 3.0/FPC 3.2.2

taazz

  • Hero Member
  • *****
  • Posts: 5368
Re: How to automatically free classes/objects?
« Reply #8 on: March 08, 2016, 03:36:09 am »

fL is TStringList index on the fieldnames which have the TFieldObject attached to it.
What I want to confirm is this:

1. If I set the OwnsObjects property of fL and I free fL, the Objects will be freed;
Yes that is correct.
2. Because Objects do not automatically free their fields, the TFieldControl objects will remain. even if the Objects are freed, unless I free the FieldControl objects themselves.
true you can also use the destructor to free them.
3. If I free the TFieldControl objects, the controls hold will still occupy memory,
Correct you need to free them manually.
because TFieldControl is not a record,
irrelevant record or class you still have to free the objects.
and fldLabel and fldControl are allocated on the heap. If they were assigned to other objects eg. SomeFieldControl := TFieldControl, SomeFieldControl will still be pointing to the controls even if the TFieldControl was freed.
Yes.
4. If I set the TLabel and TControl properties of the TFieldControl to nil, without freeing the TLabel and TControl before, SomeFieldControl would be unaffected.
1) before what?
2)define unaffected.

5. If  TFieldControl is created via a constructor and destructor freeing TFieldControl will not free fldLabel and fldControl if the destructor is not called or does not explicitly Free fldLabel and fldControl
again TfieldControl is a class by it self write a TFieldControl.destroy to destroy those fields when it is freed. I don't  see any problem.
6. if pnlControls and pnlMemo are freed all the controls on them will also be freed.
Yes the owner mechanism is in place to handle this kind of situations it also handles the case of invalid references in the premature destruction of the owned controls, use it, it will serve you well.

Pont 3 looks questionable, ie freeing TFieldControl will probably nil the memory pointers allocated to fldLabel and fldControl, making SomeFieldControl invalid.
That is a false assumption. Freeing TFieldControl will render the variable reference invalid and the memory returned to the memory manager for reassigning there is no automatic clean up performed in the memory and for a short period of time you might be able to access the values in the internal fields but it is not safe to even try it outside a test environment.
If I did SomeFieldControl.Assign(FieldControl), will SomeFieldControl still be valid  if FieldControl was freed without freeing fldLabel and fldControl because SomeField control uses its own storage for its pointers
in this case an exception will be raised on one hand the assign method is introduced in tpersistent you are using tobject and on the other you haven't  override the assign method that will raise the default assign exception can't assign X to X. In case that you write your own assign method you can go both ways, ee either copy the link to the controls or create new controls and copy their properties over, creating a duplicate.

I still do not see the problem you are trying to solve.
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

vfclists

  • Hero Member
  • *****
  • Posts: 1013
    • HowTos Considered Harmful?
Re: How to automatically free classes/objects?
« Reply #9 on: March 08, 2016, 08:43:49 am »
Thanks for the clarification taazz

This is the problem I am trying to solve.

The routine which uses the FieldControl object is shared by other forms in the program. The fL list is temporary list allocated of the stack which is used to point to the FieldControl objects to help manage the creation of the controls, so after the controls are created and placed on the forms, fL will go out of scope and the Objects will be freed, but the controls created should remain on the forms.

I need to verify that after flList and the Objects attached to it are freed, the controls will remain. I want to understand is the memory management process, as TFieldControl, fldLabel and fldControl are all pointers, and that setting a pointer to nil means that freeing the object which holds that pointer will deny the memory manager access to the objects (in this case the controls) that were created.

The main thing for me is that if fldLabel and fldControl are set to nil and the TFieldControl freed, because the controls are owned by an TPanel on the calling form, they will still remain.
Lazarus 3.0/FPC 3.2.2

taazz

  • Hero Member
  • *****
  • Posts: 5368
Re: How to automatically free classes/objects?
« Reply #10 on: March 08, 2016, 10:24:24 am »
Thanks for the clarification taazz

This is the problem I am trying to solve.

The routine which uses the FieldControl object is shared by other forms in the program. The fL list is temporary list allocated of the stack which is used to point to the FieldControl objects to help manage the creation of the controls, so after the controls are created and placed on the forms, fL will go out of scope and the Objects will be freed, but the controls created should remain on the forms.
false, all classes are allocated on the heap even the fl list.
I need to verify that after flList and the Objects attached to it are freed, the controls will remain.
Yes they will remain.
I want to understand is the memory management process, as TFieldControl, fldLabel and fldControl are all pointers, and that setting a pointer to nil means that freeing the object which holds that pointer will deny the memory manager access to the objects (in this case the controls) that were created.
The memory manager only manages the memory taken from the system ee, it will get memory from the system in blocks and put it in its cache, it will give you memory from that cache when you call getmem and return the memory you free to that cache, it does not do anything else. setting a pointer to nill does not free the memory referenced from that pointer if you do not free them your self.
The main thing for me is that if fldLabel and fldControl are set to nil and the TFieldControl freed, because the controls are owned by an TPanel on the calling form, they will still remain.
as long as you haven't written any code to free them your self, they will never get freed, except from the owner, setting the fldxxxxx variables to nil will not change anything, except perhaps your ability to access the controls from those two variables and some sort of safety feeling you might get.
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11453
  • FPC developer.
Re: How to automatically free classes/objects?
« Reply #11 on: March 08, 2016, 11:18:28 am »
In addition to Taaz, the memory manager knows all blocks, and has no way of knowing which blocks are still needed, and which not.

The automated types like strings manage this information with refcounting in their own space, but this only works for types you can't nest.

Thaddy

  • Hero Member
  • *****
  • Posts: 14373
  • Sensorship about opinions does not belong here.
Re: How to automatically free classes/objects?
« Reply #12 on: March 08, 2016, 11:34:01 am »
And there is also the option to use TP style objects instead of classes. These are indeed stack centric and not heap centric. Be careful with finalization, though. With some thought it is possible to install e.g. the Bohm garbage collector when using old school objects.
« Last Edit: March 08, 2016, 11:38:02 am by Thaddy »
Object Pascal programmers should get rid of their "component fetish" especially with the non-visuals.

Blestan

  • Sr. Member
  • ****
  • Posts: 461
Re: How to automatically free classes/objects?
« Reply #13 on: March 08, 2016, 12:03:42 pm »
garbage collection is pointless if you write consistent code...
if you plan to use FPC for professional programs learn to live without GC :)))
when you aquire some skills you will understand what i mean :)
this is the power of real languages .. you control everything but you are responsible for everything ....

ps:

btw explore one other paradigm : object reusage via objects/strings/memory pools or constant buffers - this is my favorite and makes the programs run faster with small/constant memory footprint
« Last Edit: March 08, 2016, 12:07:17 pm by Blestan »
Speak postscript or die!
Translate to pdf and live!

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11453
  • FPC developer.
Re: How to automatically free classes/objects?
« Reply #14 on: March 08, 2016, 12:15:44 pm »
With some thought it is possible to install e.g. the Bohm garbage collector when using old school objects.

If I had a dime for every time somebody brought that factoid up, and didn't have any working examples to show for it......

TP objects solve zero, zip nada. The manual management is just different, and when stack based they are not even objects since they miss the polymorphism aspect.
« Last Edit: March 08, 2016, 12:17:17 pm by marcov »

 

TinyPortal © 2005-2018