allocates ~200MB memory on each button click when compiled in Default mode, i.e. -O1 and heaptrace. I can see raising curve in System Monitor.
When compiled with -O3 and no debug info and no heaptrsace, the curve in System Monitor is flat. It looks like it does not allocate anything. Is it just an optimalization? Allocated memory is not used after all. It's the same when aPI is global variable.
Thanks
EDIT: It's FPC trunk and Linux.
Title: Re: GetMem question
Post by: Warfley on January 26, 2023, 02:51:57 pm
No this is to be expected. Modern Operating Systems use so called virtual memory, which only get's mapped onto physical memory when it is used.
On Unix systems you can easiely see virtual and physical memory usege. For example:
MiB Mem : 15941.52+total, 14512.57+free, 1284.270 used, 405.113 buff/cache
MiB Swap: 4096.000 total, 4096.000 free, 0.000 used. 14657.25+avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
544 frederic 20 0 1048988 578216 172 R 86.67 3.542 0:00.13 test
Which no has a massive physical memory usage (it's not quite the virutal one because operating systems are complicated).
This is actually quite adventaguous for development, because this means that (virtual) memory is free, and you can allocate as much as you want, and it will only be physically allocated when you use it. This allows you to do things like when creating a list, pre-allocate all the memory you could possibly need (e.g. a gigabyte of data), and then fill that list. The memory will only be used as much as you filled the list. This can be quite advantaguous for example for gemoetricly growing datastructures or things like that.
Title: Re: GetMem question
Post by: Blaazen on January 26, 2023, 03:22:03 pm
Thanks, I was wondering why SetLength(DynArray) allocates physical memory immediatelly and GetMem() doesn't.
Title: Re: GetMem question
Post by: Warfley on January 26, 2023, 03:35:04 pm
If you look at the documentation for SetLength: https://www.freepascal.org/docs-html/rtl/system/setlength.html
Quote
In case the length is set to a larger length than the current one, the new elements are zeroed out for a dynamic array. For a string, the string is zero-terminated at the correct length.
SetLength initializes the elements, which is touching them.
The same is btw also true for new for managed types: With byte array:
MiB Mem : 15941.52+total, 14796.17+free, 1000.070 used, 405.855 buff/cache
MiB Swap: 4096.000 total, 4096.000 free, 0.000 used. 14941.45+avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
731 frederic 20 0 1048992 274016 180 R 86.67 1.679 0:00.13 test
This is because for managed types new calls Initialize (https://www.freepascal.org/docs-html/rtl/system/initialize.html) on the data, which will touch the data once. Similar "Dispose" calls Finalize(https://www.freepascal.org/docs-html/rtl/system/finalize.html) on the data.
Both of this is required for managed types to work properly, so when you allocate memory with GetMem and dispose with FreeMem, you must call initialize and finalize manually: