메모리 매핑된 세그먼트와 힙이 만날 때까지 계속 증가합니까?

메모리 매핑된 세그먼트와 힙이 만날 때까지 계속 증가합니까?

나는 두 가지 소스, 즉 프로세스의 메모리 레이아웃에 있는 메모리 매핑 세그먼트에서 공유 메모리 세그먼트의 범위를 찾으려고 했습니다.


~에서https://manybutfinite.com/post/anatomy-of-a-program-in-memory/, 프로세스의 메모리 레이아웃 다이어그램을 찾았습니다.

메모리 매핑된 세그먼트와 힙이 만날 때까지 계속 증가합니까?

아니면 스택 세그먼트의 RLIMIT_STACK과 유사하게 두 세그먼트의 성장에 제한이 있습니까?

여기에 이미지 설명을 입력하세요.


Linux 프로그래밍 인터페이스에서

힙 및 스택 증가를 위한 공간을 허용하기 위해 공유 메모리 세그먼트는 가상 주소 0x40000000에서 시작하여 연결됩니다. 매핑 매핑(49장)과 공유 라이브러리(41장 및 42장)도 이 영역에 배치됩니다. (커널 버전과 프로세스의 RLIMIT_STACK 리소스 제한 설정에 따라 공유 메모리 맵과 메모리 세그먼트의 기본 배치에 약간의 차이가 있습니다.) 주소 0x40000000은 커널 상수 TASK_UNMAPPED_BASE로 정의됩니다.

공유 메모리 세그먼트가 TASK_UNMAPPED_BASE에서 시작하여 위쪽으로 증가합니까?

위 그림은 공유 메모리 세그먼트가 아래쪽으로 증가하는 것을 보여주므로 위쪽으로 성장합니까, 아니면 아래쪽으로 성장합니까?

여기에 이미지 설명을 입력하세요.

감사해요.

답변1

mmap세그먼트 및 힙 세그먼트 에는 일부 제한 사항이 적용됩니다 . RLIMIT_AS사용 가능한 총 주소 공간을 결정합니다. 여기에는 프로그램이 만들 수 있는 모든 메모리 할당이 포함됩니다. RLIMIT_DATA데이터 세그먼트의 최대 크기를 결정합니다.

커널은 이러한 제한에 대해 스택 확장 mmapbrk(힙 할당)을 확인합니다. 또한 충돌 가능성이 있는 세그먼트에 대한 할당을 확인하므로 세그먼트가 서로 덮어쓰지 않게 됩니다(예를 들어 참조).힙 할당에 대해 수행되는 검사brk). 할당이 불가능하면 프로그램에 적절하게 "알려집니다". C 라이브러리는 오류를 반환 ENOMEM하고 스택을 확장할 수 없으면 brk커널은 다음과 같이 프로그램을 종료합니다.SIGSEGV

공유 메모리 세그먼트(엄격히 말하면 커널 관점에서 가상 메모리 영역)가 커지는 방식은 메모리 레이아웃에 따라 달라지며, 이는 프로세스마다 매우 다를 수 있습니다. 대부분의 아키텍처에서 "전통적인" 메모리 매핑은 TASK_UNMAPPED_BASE; 비전통적인 메모리 매핑은 하향식 할당을 초래합니다. 바라보다arch_pick_mmap_layout()그리고mmap_is_legacy()x86 아키텍처를 예로 들어 보겠습니다. setarch' 플래그를 사용하여 이전 메모리 맵으로 전환 할 수 있습니다 -L(아래 예 참조).

실제로 /proc/$$/maps로드된 공유 라이브러리의 주소(있는 경우)와 로드된 순서를 보고 검사하여 세그먼트가 어떻게 증가하는지 이해할 수 있습니다. 동적 링커는 항상 먼저 로드됩니다. 해당 주소가 다른 라이브러리보다 낮으면 할당은 상향식이고, 그렇지 않으면 하향식입니다. 64비트 x86 시스템의 출력을 비교하십시오 cat /proc/self/maps.setarch x86_64 -L cat /proc/self/maps

관련 정보