I have an app with a number of worker threads, one for each core. On a modern 8 core machine, I have 8 of these threads. My app loads a lot of plugins, which also have their own worker threads. Because the app uses huge blocks of memory (photos, eg. 200 MB) I have memory fragmentation problem. The problem is that every thread allocates the {$MAXSTACKSIZE ...} of address space. It's not using the physical memory but the adress space. I reduced the MAXSTACKSIZE from 1MB to 128KB and it seems to work, but I don't now if I'm near to the limit. Is there any possibility to measure how much stack is really used?
In Visual Studio the default stack size is 1 MB i think, so with a recursion depth of 10,000 each stack frame can be at most ~100 bytes which should be sufficient for a DFS algorithm. Most compilers including Visual Studio let you specify the stack size.
size() method in Java is used to get the size of the Stack or the number of elements present in the Stack. Parameters: The method does not take any parameter. Return Value: The method returns the size or the number of elements present in the Stack.
The default Ingres stack size is 65536 bytes or 64 KB.
Stack size is just tradeoff between ability to create many threads and possibility of stack overflow in one of them. The more stack size is, the less number of threads you can create and the less possibility of stack overflow is.
Use this to compute the amount of memory committed for the current thread's stack:
function CommittedStackSize: Cardinal;
asm
mov eax,[fs:$4] // base of the stack, from the Thread Environment Block (TEB)
mov edx,[fs:$8] // address of lowest committed stack page
// this gets lower as you use more stack
sub eax,edx
end;
Another idea I don't have.
For the sake of completeness, I am adding a version of the CommittedStackSize
function provided in opc0de's answer for determining the amount of used stack that will work both for x86 32- and 64-bit versions of Windows (opc0de's function is for Win32 only).
opc0de's function queries the address of the base of the stack and the lowest committed stack base from Window's Thread Information Block (TIB). There are two differences among x86 and x64:
FS
segment register on Win32, but by the GS
on Win64 (see here)Additionally note that there is a small difference in the BASM code, because on x64, abs
is required to make the assembler use an absolute offset from the the segment register.
Therefore, a version that will work on both Win32 and Win64 version looks like this:
{$IFDEF MSWINDOWS}
function CommittedStackSize: NativeUInt;
//NB: Win32 uses FS, Win64 uses GS as base for Thread Information Block.
asm
{$IFDEF WIN32}
mov eax, [fs:04h] // TIB: base of the stack
mov edx, [fs:08h] // TIB: lowest committed stack page
sub eax, edx // compute difference in EAX (=Result)
{$ENDIF}
{$IFDEF WIN64}
mov rax, abs [gs:08h] // TIB: base of the stack
mov rdx, abs [gs:10h] // TIB: lowest committed stack page
sub rax, rdx // compute difference in RAX (=Result)
{$ENDIF}
{$ENDIF}
end;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With