제한 사항 받기(2)매뉴얼 페이지에는 다음과 같은 정의가 있습니다.
RLIMIT_AS 프로세스의 가상 메모리(주소 공간)의 최대 크기(바이트)입니다. 이 제한은 brk(2), mmap(2) 및 mremap(2)에 대한 호출에 영향을 미치며 이 제한을 초과하면 ENOMEM 오류와 함께 실패합니다. 반품자동 스택 확장실패합니다(sigatstack(2)를 통해 사용할 수 있는 대체 스택이 없으면 프로세스를 종료하기 위해 SIGSEGV가 생성됩니다). 값이 long이므로 32비트 long을 사용하는 머신에서는 이 제한이 최대 2GiB이거나 이 리소스가 무제한입니다.
여기서 "자동 스택 확장"은 무엇을 의미합니까? Linux/UNIX 환경의 스택은 필요에 따라 증가합니까? 그렇다면 구체적인 메커니즘은 무엇인가?
답변1
Linux의 정확한 메커니즘은 다음과 같습니다.익명 매핑의 페이지 오류 처리너"증가하는 할당"인지 확인하세요.스택처럼 확장해야 합니다. VM 영역 기록에 그렇게 해야 한다고 표시된 경우 시작 주소를 조정하여 스택을 확장할 수 있습니다.
페이지 폴트가 발생하면 주소에 따라 스택 확장을 통해 처리할 수 있습니다(오류 제거도 가능). 모든 사용자 프로그램은 가상 메모리의 "실패 시 성장" 동작을 요청하고 시스템 호출 MAP_GROWSDOWN
에 플래그를 전달할 수 있습니다.mmap
사용자 프로그램에서도 이 메커니즘을 사용할 수 있습니다.
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/mman.h>
int main() {
long page_size = sysconf(_SC_PAGE_SIZE);
void *mem = mmap(NULL, page_size, PROT_READ|PROT_WRITE, MAP_GROWSDOWN|MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
if (MAP_FAILED == mem) {
perror("failed to create growsdown mapping");
return EXIT_FAILURE;
}
volatile char *tos = (char *) mem + page_size;
int i;
for (i = 1; i < 10 * page_size; ++i)
tos[-i] = 42;
fprintf(stderr, "inspect mappping for originally page-sized %p in /proc... press any key to continue...\n", mem);
(void) getchar();
if (munmap(mem, page_size))
perror("failed munmap");
return EXIT_SUCCESS;
}
메시지가 표시되면 프로그램의 pid(pass ps
)를 찾아 /proc/$THAT_PID/maps
원래 영역이 어떻게 커지는지 확인합니다.
답변2
예, 스택은 동적으로 증가합니다. 스택은 메모리의 맨 위에 있으며 힙을 향해 아래쪽으로 증가합니다.
--------------
| Stack |
--------------
| Free memory|
--------------
| Heap |
--------------
.
.
새 함수가 호출되면 힙은 위쪽으로 커지고(malloc이 수행될 때마다) 스택은 아래쪽으로 늘어납니다. 힙은 프로그램의 BSS 부분 위에 위치합니다. 이는 프로그램의 크기와 힙에 메모리를 할당하는 방법도 프로세스의 최대 스택 크기에 영향을 미친다는 것을 의미합니다. 일반적으로 스택 크기는 무한합니다(힙과 스택 영역이 만나거나 덮어써질 때까지 스택 오버플로 및 SIGSEGV가 발생함 :-)
이는 사용자 프로세스에만 작동하며 커널 스택은 항상 고정됩니다(보통 8KB).