Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is a safe Maximum Stack Size or How to measure use of stack?

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?

like image 583
Steffen Binas Avatar asked May 27 '11 09:05

Steffen Binas


People also ask

What is the maximum size of stack?

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.

How do you measure 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.

What is the maximum stack size Linux?

The default Ingres stack size is 65536 bytes or 64 KB.

What is the stack size?

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.


2 Answers

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.

like image 144
opc0de Avatar answered Sep 28 '22 08:09

opc0de


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:

  • TIB is pointed to by the FS segment register on Win32, but by the GS on Win64 (see here)
  • The absolute offsets of items in the structure differ (mostly because some items are pointers, i.e. 4 bytes and 8 bytes on Win32/64, respectively)

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;
like image 23
PhiS Avatar answered Sep 28 '22 08:09

PhiS