본문 바로가기

Windows

Thread Stack Size

예전 프로젝트 때, 번역했던 것.

그냥 백업 겸 올려본다.

 

각각의 새로운 Thread 나 Fiber 는 예약되고 초기화된 자기 자신만의 Stack 메모리 공간을 예약 받는다. 그러므로, 예약 공간은 가상 주소 범위에 제한을 가진다. 제공된 초기화된 페이지는 그 것이 참조될 때 까지 물리적 메모리에 올라가지 않는다. 그리고 물리적 메모리의 크기 보다 한 페이지 더 큰 사이즈를 가진다거나 하는 전체 시스템 할당한계가 생기면 페이지를 제거할 수 있다. 시스템은 메모리가 필요할 때 마다 조금씩 예약된 Stack 메모리를 할당할 수 있다. 물론, 전체 시스템 메모리보다 한 페이지 작은 크기만큼이다. 마지막 한 페이지는 Stack Overflow를 방지하기 위해 Guard Page로 사용된다. 가능한 한 작은 사이즈의 Stack 크기를 정하는 것이 좋다. 그리고 Thread 나 fiber 가 안정적으로 실행될 때 Stack을 할당하는 것이 좋다. 모든 예약된 페이지는 다른 목적으로 사용될 수 없다. Stack은 Thread 가 끝날 때 자유로워 진다.( Free ) 혹시나 다른 Thread에 의해 종료된다면 Stack은 자유로워지지( Not Free? ) 않는다. 예약되고 초기화되고 할당되는 Stack 메모리의 기본 크기는 실행 가능한 파일 헤더(PE) 에 명시되어 있다. 요청된 Byte 만큼 충분히 메모리를 예약하거나 할당할 수 없으면 Thread 나 Fiber 의 생성은 실패한다. 기본 Stack 예약 크기는 Linker에 의해 1MB로 예약되어 있다. 모든 Thread 나 Fiber에 대해서 다른 기본 Stack 크기를 설정하고 싶으면 Module Definition(.def) File 의 STACKSIZE 를 사용하라. OS는 가장 가까운 여러 시스템의 고정된 할당 단위(보통 64KB) 올림 한다. 현재 시스템의 할당 단위를 보고 싶으면 GetSystemInfo 함수를 사용하라.(원문 : The operating system rounds up the specified size to the nearest multiple of the system's allocation granularity (typically 64 KB). To retrieve the allocation granularity of the current system, use the GetSystemInfo function.) 초기화되고 할당되는 Stack 크기를 변경하기 위해서 CreateThread, CreateRemoteThread, CreateFiber의 dwStackparameter를 사용하라. 이 값들은 가장 가까운 페이지를 올림 한다. 일반적으로 초기화되고 할당된 고정 dwStackSize가 기본 예약된 크기보다 크거나 같다면 , 예약된 크기는 1MB 단위에 가장 가깝게 올림되어 새로운 할당크기로 할당된다. 예약된 Stack 크기를 바꾸기 위해서 CreateThread, CreateRemoteThread 의 dwCreationFlogs 파라미터를 STACK_SIZE_PARAM_IS_A_RESERVATION 으로 설정하라. 이는 dwStackSize 파라미터를 사용하게 한다. 이 경우, 초기화되고 할당되는 기본 크기는 PE 헤더에 포함된다. Fiber의 경우 CreateFiberEx 의 dwStackReserveSize 파라미터를 사용하라. 이는 dwStackCommitSize 파라미터를 사용한다.

원문 :

Each new thread or fiber receives its own stack space consisting of both reserved and initially committed memory. The reserved memory size represents the total stack allocation in virtual memory. As such, the reserved size is limited to the virtual address range. The initially committed pages do not utilize physical memory until they are referenced; however, they do remove pages from the system total commit limit, which is the size of the page file plus the size of the physical memory. The system commits additional pages from the reserved stack memory as they are needed, until either the stack reaches the reserved size minus one page (which is used as a guard page to prevent stack overflow) or the system is so low on memory that the operation fails.

It is best to choose as small a stack size as possible and commit the stack that is needed for the thread or fiber to run reliably. Every page that is reserved for the stack cannot be used for any other purpose.

A stack is freed when its thread exits. It is not freed if the thread is terminated by another thread.

The default size for the reserved and initially committed stack memory is specified in the executable file header. Thread or fiber creation fails if there is not enough memory to reserve or commit the number of bytes requested. The default stack reservation size used by the linker is 1 MB. To specify a different default stack reservation size for all threads and fibers, use the STACKSIZE statement in the module definition (.def) file. The operating system rounds up the specified size to the nearest multiple of the system's allocation granularity (typically 64 KB). To retrieve the allocation granularity of the current system, use the GetSystemInfo function.

To change the initially committed stack space, use the dwStackSize parameter of the CreateThread , CreateRemoteThread , or CreateFiber function. This value is rounded up to the nearest page. Generally, the reserve size is the default reserve size specified in the executable header. However, if the initially committed size specified by dwStackSize is larger than or equal to the default reserve size, the reserve size is this new commit size rounded up to the nearest multiple of 1 MB.

To change the reserved stack size, set the dwCreationFlags parameter of CreateThread or CreateRemoteThread to STACK_SIZE_PARAM_IS_A_RESERVATION and use the dwStackSize parameter. In this case, the initially committed size is the default size specified in the executable header. For fibers, use the dwStackReserveSize parameter of CreateFiberEx . The committed size is specified in the dwStackCommitSize parameter.

The SetThreadStackGuarantee function sets the minimum size of the stack associated with the calling thread or fiber that will be available during any stack overflow exceptions.