Tamanho da Pilha de Thread

Cada thread do Windows recebe uma pilha privada cujo tamanho equivale ao tamanho de pilha padrão do processo hospedeiro. No modo Standalone ou Windows Service, o tamanho da pilha é determinado pelo Delphi. Por padrão, o tamanho da pilha de uma aplicação Delphi é 1 MB. Ele pode ser alterado via Project -> Options -> Linking -> Minimum Stack Size / Maximum Stack Size.

Eles também podem ser ajustados por diretivas do compilador:

{$M minstacksize,maxstacksize}

{$MINSTACKSIZE number}

{$MAXSTACKSIZE number}

Essas configurações se aplicam somente a binários executáveis. ISAPI DLLs usam o valor padrão de tamanho de pilha do processo hospedeiro para threads internas. Isso pode ser um problema para uma aplicação uniGUI que foi projetada para trabalhar com um tamanho de pilha diferente do tamanho de pilha do processo hospedeiro da DLL. No IIS 7.0 e posteriores, o tamanho de pilha padrão é 256 KB para aplicações 32 bits e 512 KB para aplicações 64 bits. Esses valores são menores que o padrão do Delphi de 1 MB. Como resultado, uma aplicação web que roda corretamente em modo standalone pode gerar exceções inesperadas de Stack Overflow quando implantada em formato ISAPI.

O tamanho padrão de pilha de 1 MB para aplicações Delphi é na verdade um valor grande para aplicações típicas. Uma aplicação Delphi não deve depender do tamanho da pilha para funcionar corretamente. A pilha é uma área de armazenamento temporário usada para variáveis locais dentro de funções e procedimentos. É sensato manter o uso de variáveis locais ao mínimo ao projetar uma aplicação. Por exemplo, o trecho a seguir usa um array local alocado na pilha:

procedure TMyClass.DoCalculate;
var
  MyCalcArray: array[1..10240] of Integer;
  I: Integer;
begin
  for I := 1 to 10240 do
    MyCalcArray[I] := I * 10;
end;

Esse array local consome memória de pilha e deve ser evitado; desenvolvedores devem usar estruturas de dados dinâmicas que são criadas no heap:

var
  MyCalcArray: array of Integer;
  I: Integer;
begin
  SetLength(MyCalcArray, 10240);
  for I := 1 to Length(MyCalcArray) do
    MyCalcArray[I] := I * 10;
end;

Se sua aplicação travar com uma mensagem de Stack Overflow, isso é sinal de uma chamada recursiva (um bug) ou de que o uso de pilha da sua aplicação excede a configuração padrão de pilha. Nesse caso, você deve reduzir o uso de pilha alterando seu código/fluxo lógico ou aumentar o tamanho padrão da pilha da aplicação.

Observe que Stack Overflow é uma condição séria sem opção de recuperação. Em alguns casos, a condição de Stack Overflow registrará um erro no arquivo de log do uniGUI com uma mensagem de exceção na tela. Em uma aplicação ISAPI, um erro de Stack Overflow pode encerrar seu pool ISAPI silenciosamente sem qualquer mensagem de exceção na tela ou entrada de log do uniGUI. No entanto, você pode ver um evento no Visualizador de Eventos do Windows indicando que seu application pool foi encerrado e reiniciado devido a um erro inesperado.

Alterando o Tamanho de Pilha Padrão da Aplicação ISAPI

circle-exclamation

As linhas abaixo se aplicam somente ao uniGUI build 1607 ou anterior.

Em qualquer caso, você ainda pode querer alterar o tamanho da pilha da sua aplicação DLL que é imposto pelo processo worker do IIS. O uniGUI fornece uma maneira simples de conseguir isso.

1

Etapa

No ServerModule, expanda ISAPIOptions e defina AsyncMode para True.

2

Etapa

Defina ThreadStackSize para o valor desejado. No exemplo abaixo o tamanho da pilha é definido para 2 MB.

clip0103

Observe que essas configurações se aplicam somente a módulos ISAPI DLL. Para aplicações Standalone e Service o tamanho da pilha deve ser ajustado usando os métodos convencionais descritos acima.