[fpc-devel] FPC memory manager and OS/2 - heap sub-allocation

Tomas Hajny XHajT03 at hajny.biz
Tue Jun 30 17:43:38 CEST 2026


On 2026-06-27 18:26, runewalsh via fpc-devel wrote:


Hi Rika,

Thanks for your response!

> — Google search doesn’t seem to back that up: they say that DosAllocMem 
> is only limited by the address space (?).

I didn't find anything like that in the official documentation either, 
but I found it mentioned in some discussion forum, IIRC.


> — The compiler started eating noticeably more memory after some change 
> related to ctask.pas; that might be the culprit. For another data point 
> (and the exact ctask.pas commit): 
> https://gitlab.com/freepascal.org/fpc/source/-/work_items/41670.

Yes, I understand that. I'm not sure if I can expect any decrease there, 
although that would be nice, of course. However, as mentioned 
previously, I monitored amount of available physical memory (as reported 
by the operating system) at the moment when the allocation failed and it 
didn't show all the memory having been allocated.


> — Does -dLEGACYHEAP help you? :) If anything, it *increases* the number 
> of OS allocations (4× asymptotically).

I'll check that and let you know.


> — OS allocations are roughly RoundUp(min(used memory div 16, 
> GrowHeapSize2), 64 KB). The default GrowHeapSize2 is 1 MB, which kicks 
> in after ≈50 such allocations. You can tweak GrowHeapSize2 to some 
> extent (this ability was inherited from oldheap.inc and doesn’t seem 
> useful; I’ve even considered removing it entirely). OS allocations 
> start at a natural minimum of 64 KB, which is not configurable; the 
> idea is that programs and especially threads can be tiny, in which case 
> they benefit from fitting everything into one, or a few, 64 KB OS 
> chunks.

Interesting, especially the part clarifying that the allocated blocks 
grow depending on the overall amount of memory already used (used memory 
div 16)... That might mean that at certain point in time, the operating 
system may not be able to allocate a continuous block of memory of the 
requested size (if the memory became fragmented by previous allocations 
and deallocations), although the overall amount of free memory is still 
much higher than the newly requested block. Do I assume correctly that 
the memory manager wouldn't try allocating a smaller block in such a 
case? I'm not sure about the likelihood of this really happening, just 
an idea...

In addition, thinking about it a bit more, I just noticed another 
potential reason of the misalignment between the overall memory still 
available and the memory allocation failing... Originally, OS/2 didn't 
allow allocation of more than 512 MB of RAM per process (that limit has 
its reasons, but those go beyond this post). Later OS/2 versions 
provided a solution for overcoming that limitation, but that solution 
has its own gotchas which is the reason why I don't use that by default 
within the OS/2 RTL. It's possible that the trunk compiler hits this 
limit nowadays. :-( If this is the case, I might try allocation of the 
"high memory" (> 512 MB address space) area and see if that helps... If 
it does, it isn't an optimal solution (certain OS/2 API functions 
wouldn't be able to work with memory blocks from this "high memory" :-( 
), but I believe that this shouldn't affect the compiler itself (it 
might easily affect the text mode IDE, though :-((( ). But let's see 
what happens...


> — Second commit of 
> https://gitlab.com/freepascal.org/fpc/source/-/merge_requests/1498 
> should slightly improve the situation through a dedicated design for 
> 32-bit sizes that leverages 8-byte alignment.

OK, thanks.

Tomas


More information about the fpc-devel mailing list