Ste*_*nas 9 delphi stack delphi-2010
我有一个带有多个工作线程的应用程序,每个核心一个.在现代的8核机器上,我有8个这样的线程.我的应用程序加载了很多插件,这些插件也有自己的工作线程.因为应用程序使用大块内存(照片,例如200 MB),我有内存碎片问题.问题是每个线程都分配了{$ MAXSTACKSIZE ...}的地址空间.它不使用物理内存,而是使用地址空间.我将MAXSTACKSIZE从1MB降低到128KB,似乎可行,但如果我接近极限,我现在不行.有没有可能测量真正使用多少堆栈?
opc*_*0de 12
使用它来计算为当前线程堆栈提交的内存量:
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;
Run Code Online (Sandbox Code Playgroud)
我没有的另一个想法.
为了完整起见,我CommittedStackSize在opc0de的答案中添加了一个函数版本,用于确定对x86 32位和64位版本的Windows都有效的堆栈使用量(opc0de的函数仅适用于Win32).
opc0de的函数从Window的线程信息块(TIB)查询堆栈基址的地址和最低的已提交堆栈库.x86和x64有两个不同之处:
FSWin32上的段寄存器指向TIB ,但是通过GSon Win64 指向(参见此处)另请注意,BASM代码存在细微差别,因为在x64上,abs需要使汇编程序使用与段寄存器的绝对偏移量.
因此,适用于Win32和Win64版本的版本如下所示:
{$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;
Run Code Online (Sandbox Code Playgroud)