How to automatically free classes/objects? lazarus / 62-General ---------------------------------------------------------------------- aradeonas · 2016-03-01 19:50 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 · 2016-03-01 20:15 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 · 2016-03-01 20:19 OK. marcov what ways you think is best for now? ---------------------------------------------------------------------- vfclists · 2016-03-07 06:41 Quote from: aradeonas on March 01, 2016, 08:50:51 pmSubject 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 ---------------------------------------------------------------------- marcov · 2016-03-07 08:19 Quote from: aradeonas on March 01, 2016, 09:19:13 pmOK. 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. ---------------------------------------------------------------------- vfclists · 2016-03-07 12:07 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? ---------------------------------------------------------------------- Bart · 2016-03-07 12:37 Quote from: vfclists on March 07, 2016, 01:07:57 pmIf 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 · 2016-03-07 20:41 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][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i   TFieldControl= class(TObject)    fldLabel:TLabel;    fldControl: TWinControl;  end;       Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i begin  fL := TStringList.Create;  d := dS.Dataset;  d.GetFieldNames(fL);  // create fields  for i := 0 to fL.Count - 1 do  begin    if not Assigned(fL.Objects[i]) then    begin      fLd := d.FieldByName(fL[i]);      fLd.DisplayLabel := SetDisplayLabel(fLd.FieldName);      fL.Objects[i] := TFieldControl.Create;      TFieldControl(fL.Objects[i]).fLdLabel := TLabel.Create(nil);      TFieldControl(fL.Objects[i]).fLdLabel.Caption := fLd.DisplayLabel;       case fLd.DataType of      ftString, ftSmallint, ftInteger, ftWord,   ftfLoat, ftCurrency, ftBCD, ftDate,  ftTime, ftDateTime,ftWideString,  ftLargeint,ftTimeStamp:        begin          e := TDBEdit.Create(pnlControls);          e.DataSource := dS;          e.DataField := fL[i];          e.Width := ctlLayoutEditWidth;          TFieldControl(fL.Objects[i]).fLdControl := e;        end;         ftMemo, ftFmtMemo, ftWideMemo:         begin           if not Assigned(sbControls) then             sbControls := TScrollBox.Create(pnlMemos);           m := TDBMemo.Create(pnlMemos);           m.DataSource := dS;           m.DataField := fL[i];           m.Parent := sbControls;           m.Align := alTop;           m.ScrollBars := ssAutoBoth;           m.Font.Name := 'Courier New';           TFieldControl(fL.Objects[i]).fLdControl := m;         end;         ftBoolean:         begin           c := TDBCheckBox.Create(pnlControls);           c.DataSource := dS;         c.DataField := fL[i];           c.Caption := fLd.DisplayLabel;         TFieldControl(fL.Objects[i]).fLdControl := c;         end;      end;  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 ---------------------------------------------------------------------- taazz · 2016-03-08 02:36 Quote from: vfclists on March 07, 2016, 09:41:51 pm 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. Quote from: vfclists on March 07, 2016, 09:41:51 pm2. 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. Quote from: vfclists on March 07, 2016, 09:41:51 pm3. If I free the TFieldControl objects, the controls hold will still occupy memory, Correct you need to free them manually. Quote from: vfclists on March 07, 2016, 09:41:51 pmbecause TFieldControl is not a record, irrelevant record or class you still have to free the objects. Quote from: vfclists on March 07, 2016, 09:41:51 pmand 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. Quote from: vfclists on March 07, 2016, 09:41:51 pm4. 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. Quote from: vfclists on March 07, 2016, 09:41:51 pm5. 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. Quote from: vfclists on March 07, 2016, 09:41:51 pm6. 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. Quote from: vfclists on March 07, 2016, 09:41:51 pm 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. Quote from: vfclists on March 07, 2016, 09:41:51 pmIf 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. ---------------------------------------------------------------------- vfclists · 2016-03-08 07:43 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. ---------------------------------------------------------------------- taazz · 2016-03-08 09:24 Quote from: vfclists on March 08, 2016, 08:43:49 amThanks 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. Quote from: vfclists on March 08, 2016, 08:43:49 amI need to verify that after flList and the Objects attached to it are freed, the controls will remain. Yes they will remain. Quote from: vfclists on March 08, 2016, 08:43:49 amI 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. Quote from: vfclists on March 08, 2016, 08:43:49 amThe 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. ---------------------------------------------------------------------- marcov · 2016-03-08 10:18 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 · 2016-03-08 10:34 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. ---------------------------------------------------------------------- Blestan · 2016-03-08 11:03 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 ---------------------------------------------------------------------- marcov · 2016-03-08 11:15 Quote from: Thaddy on March 08, 2016, 11:34:01 am 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. ---------------------------------------------------------------------- Leledumbo · 2016-03-08 11:27 Quote from: Thaddy on March 08, 2016, 11:34:01 amWith some thought it is possible to install e.g. the Bohm garbage collector when using old school objects. If you've managed to write an fp memory manager with Boehm backend, then everything else would be using that memory manager and should work anywhere memory allocation is required. Not limited to old school objects or some other types. ---------------------------------------------------------------------- Thaddy · 2016-04-03 08:21 Quote from: Leledumbo on March 08, 2016, 12:27:26 pmQuote from: Thaddy on March 08, 2016, 11:34:01 amWith some thought it is possible to install e.g. the Bohm garbage collector when using old school objects. If you've managed to write an fp memory manager with Boehm backend, then everything else would be using that memory manager and should work anywhere memory allocation is required. Not limited to old school objects or some other types. Article 21646 by Barry Kelly on the delphi community forum. I did one for KOL and another version for FPC if you are interested. But based on that code you are quite capable of doing that yourself in an hour or so. It was discussed a couple of years ago with Florian. Apart from performance issues (that could be/are overcome) Florian had several more objections, i believe because it also requires a paradigm shift and can not be used as is. You have to register objects for finalization, for one. But there is working code around, not only by Barry or me. ---------------------------------------------------------------------- aradeonas · 2016-04-03 08:30 I am not a pro in Pascal so I cant see through it but I see more libraries with Interface base system with main benefit of there is no need to free interfaces. ---------------------------------------------------------------------- Thaddy · 2016-04-03 08:47 Interface based systems are essentially ARC. Garbage collection is different. My work on garbage collection is more or less out of interest. For practical application I too prefer interface based management. ---------------------------------------------------------------------- aradeonas · 2016-04-03 09:01 Quote from: Thaddy on April 03, 2016, 10:47:31 amInterface based systems are essentially ARC. Garbage collection is different. My work on garbage collection is more or less out of interest. For practical application I too prefer interface based management. That's the point I cant understand,why interfaces have this ability and why it didn't use more? I see more interface based management but is it really correct using interfaces for this subject and it is good really? If it is why there is a need for garbage collection? ---------------------------------------------------------------------- Thaddy · 2016-04-03 10:04 http://blogs.embarcadero.com/abauer/2013/06/14/38948 Is a good write up by the former chief engineer of Delphi. ---------------------------------------------------------------------- marcov · 2016-04-03 10:55 Quote from: Thaddy on April 03, 2016, 12:04:11 pmhttp://blogs.embarcadero.com/abauer/2013/06/14/38948 Is a good write up by the former chief engineer of Delphi. No, not at all. It doesn't mention cycles.