실제로 스택을 늘리는 것은 어렵고 때로는 불가능합니다. 가상 메모리에 대한 이해가 필요한 이유를 이해하려면.
Ye Olde Days의 단일 스레드 응용 프로그램과 연속 메모리에서 프로세스 주소 공간의 세 가지 구성 요소는 코드, 힙 및 스택이었습니다. 이 세 가지 방법은 OS에 따라 다르지만 일반적으로 코드는 메모리의 맨 아래부터 시작하여 힙이 다음에 올라가고 위로 올라 갔으며 스택은 메모리의 맨 위에서 시작하여 내려갔습니다. 운영 체제 용으로 예약 된 메모리도 있지만 무시할 수 있습니다. 당시의 프로그램은 스택 오버플로가 다소 급격했습니다. 스택이 힙에 충돌하고 어떤 업데이트가 먼저 업데이트되었는지에 따라 불량 데이터로 작업하거나 서브 루틴에서 메모리의 임의의 부분으로 돌아갑니다.
메모리 관리는이 모델을 다소 변경했습니다. 프로그램 관점에서 프로세스 메모리 맵의 3 가지 구성 요소가 여전히 존재하지만 일반적으로 동일한 방식으로 구성되었지만 이제 각 구성 요소는 독립적 인 세그먼트로 관리되었으며 MMU는 프로그램이 세그먼트 외부의 메모리에 액세스하려고 한 경우 OS 가상 메모리를했다하면이 필요가 없었다 또는 원하는 전체 주소 공간에 대한 프로그램 액세스 권한을 부여 할 수 있습니다. 따라서 세그먼트에는 고정 경계가 할당되었습니다.
그렇다면 프로그램에 전체 주소 공간에 대한 액세스 권한을 부여하는 것이 바람직하지 않은 이유는 무엇입니까? 그 메모리는 스왑에 대한 "커밋 요금"을 구성하기 때문에; 언제든지 다른 프로그램의 메모리를위한 공간을 만들기 위해 하나의 프로그램에 대한 메모리의 일부 또는 전부를 교체해야 할 수도 있습니다. 모든 프로그램이 잠재적으로 2GB의 스왑을 소비 할 수 있다면 모든 프로그램에 충분한 스왑을 제공하거나 두 프로그램이 얻을 수있는 것보다 더 많은 것을 필요로 할 가능성을 가져야합니다.
이 시점에서 충분한 가상 주소 공간을 가정 하면 필요한 경우 이러한 세그먼트를 확장 할 수 있으며 실제로 데이터 세그먼트 (힙)는 시간이 지남에 따라 커집니다. 작은 데이터 세그먼트로 시작하고 메모리 할당자가 더 많은 공간을 요청할 때 필요합니다. 이 시점에서 단일 스택으로 물리적으로 스택 세그먼트를 확장 할 수 있었을 것입니다. OS는 세그먼트 외부로 무언가를 밀어 내고 더 많은 메모리를 추가하려는 시도를 막을 수 있습니다. 그러나 이것은 특히 바람직하지 않습니다.
멀티 스레딩을 입력하십시오. 이 경우 각 스레드에는 독립적 인 스택 세그먼트가 있으며 다시 고정 크기입니다. 그러나 이제 세그먼트는 가상 주소 공간에 하나씩 배치되므로 다른 세그먼트를 이동하지 않고 한 세그먼트를 확장 할 수있는 방법이 없습니다. 프로그램은 스택에있는 메모리에 대한 포인터를 잠재적으로 가질 수 있기 때문에 수행 할 수 없습니다. 세그먼트 사이에 약간의 공간을 남겨 둘 수도 있지만 거의 모든 경우에 해당 공간이 낭비됩니다. 더 좋은 방법은 응용 프로그램 개발자에게 부담을주는 것이 었습니다. 실제로 딥 스택이 필요한 경우 스레드를 만들 때 지정할 수 있습니다.
오늘날 64 비트 가상 주소 공간을 통해 사실상 무한한 수의 스레드를 위해 사실상 무한 스택을 만들 수있었습니다. 그러나 다시 말하지만, 특히 바람직하지는 않습니다. 거의 모든 경우에 스택 오버 로우는 코드의 버그를 나타냅니다. 1GB 스택을 제공하면 해당 버그 발견이 지연됩니다.