Bookstore

Recent

Author Topic: Accumulation of garbage in memory.  (Read 346 times)

Nera

  • Jr. Member
  • **
  • Posts: 68
Accumulation of garbage in memory.
« on: February 16, 2020, 02:07:23 pm »
Good Morning.
I have a program that starts with the consumption of 12.1Mb of memory and goes up until it crosses the program. Is there a command in Lazarus that I can free up memory?

howardpc

  • Hero Member
  • *****
  • Posts: 3356
Re: Accumulation of garbage in memory.
« Reply #1 on: February 16, 2020, 02:59:06 pm »
How long is a piece of string?
Managing your program's memory allocation/deallocation is vital.
Classes that are instantiated need to be freed.
Calls to New need to be balanced by calls to Dispose, and so on.
But without sight of your code and what is causing unbridled memory consumption, there is no way to give more specific guidance. There is no magic wand that will will correct badly written programs.

winni

  • Hero Member
  • *****
  • Posts: 1114
Re: Accumulation of garbage in memory.
« Reply #2 on: February 16, 2020, 04:15:19 pm »
Hi!

Common used code sniplets to show that you should not forget to free the memory:

Code: Pascal  [Select]
  1. SL := TStringList.create;
  2. ....
  3. SL.free;
  4. // ------
  5. bmp := TBitmap.create;
  6. .....
  7. bmp.free;
  8. //------
  9. Proc := TProcess.Create(nil);
  10. .....
  11. Proc.Free
  12.  
  13.  

Winni

devEric69

  • Sr. Member
  • ****
  • Posts: 254
Re: Accumulation of garbage in memory.
« Reply #3 on: February 16, 2020, 04:47:20 pm »
Hello.

In Pascal, there's no garbage collector. It means that what you have created, allocated, must be destroyed, unallocated.
- each New(pRec) must have a corresponding Dispose(pRec).
- each Create must have a corresponding Free, or even better FreeAndNil(oMyFCreate) if its allowed where you are coding it.

How to make \ let it simple?
With a variant of the Hungarian method which explains, if you should destroy the object where you are using it, or if you shouldn't destroy it because it has to be destroyed "in the distance", somewhere else! That's all.

Globally, the rule of thumb is that you have to free the allocated memory in the same namespace, closure, call stack level, etc..., as the one where you created it, allocated it.

Two possibilities:
- you declare your oMyFo object in same the namespace where it has been created, to remind you, that you'll have to destroy it there too. For example: FoMyFoo is created in your OnFormCreate and you destroy it in your OnFormDestroy. Or your oMyFoo is created in one method and destroyed in the same method.
- now, sometimes you create an object in one place and must destroy it in another place; or you use it in a place where it should not be destroyed. In this case you write your object o_myFoo: : TMyFooObject or frm_Foo: TFrmFoo, or btn_Foo: TButton.
➔ So, if o_myFoo is a parameter of a method, it reminds you that you must not destroy it in that method! Same approach: if you declare a Fo_myFoo field, it means that your field will receive an instance of a TMyFooObject. Well, in accordance with this convention, it means that this instance could be passed as a parameter (to the constructor for example), or could be created in the constructor itself.

Reminder:
• in Pascal, finding where you have created an object is always simple, easy: that's where you have to start using it :) .
• What is clever is to understand, to remember, where it must be destroyed: where you'ra actually coding, where you're using it  ? Or alternatively, somewhere else, "in the distant"? :(

I come back to the previous example. Let's say you have a Fo_myFoo field in your Form, and that you have created an instance of TMyFooObject in a method of this Form. What can you deduce from this? You can deduce from this conventio that Fo_myFoo should not be destroyed in your Form even if that's where you created it. No, Fo_myFoo should be destroyed elsewhere: for example, in a TfpList that has its OwnsObjects = true; a list, to which you've added the Fo_myFoo; a list that has the responsibility to destroy that Fo_myFoo.

Amho, if you code with this convention and always monitor the memory release, coding with Lazarus is no more complicated than with a language that has a garbage collector.
« Last Edit: February 16, 2020, 04:58:56 pm by devEric69 »
use: Linux 64 bits (Ubuntu 18.04 LTS).
Lazarus version: 2.0.4 (svn revision: 62502M) compiled with fpc 3.0.4 - fpDebug \ Dwarf3.

avra

  • Hero Member
  • *****
  • Posts: 1827
    • Additional info
Re: Accumulation of garbage in memory.
« Reply #4 on: February 16, 2020, 06:47:47 pm »
Good Morning.
I have a program that starts with the consumption of 12.1Mb of memory and goes up until it crosses the program.
You probably have a memory leak, likely in some loop. This tool can help you locate it: https://wiki.freepascal.org/heaptrc

Is there a command in Lazarus that I can free up memory?
Yes. NameOfCreatedObject.Free
ct2laz - Conversion between Lazarus and CodeTyphon
bithelpers - Bit manipulation for standard types
pasettimino - Siemens S7 PLC lib