스택과 힙의 크기는 OS에 의해 어떻게 제한됩니까?


21

참고 : 답변 할 수있는 특정 OS를 고려해야하는 경우 Linux를 고려하십시오.

프로그램을 실행할 때마다 스택 영역과 힙 영역이있는 가상 메모리 공간이 제공됩니다.

질문 1 : 스택과 힙에 정적 크기 제한이 있습니까 (예 : 각각 2 기가 바이트), 또는 프로그램 실행 중 메모리 할당에 따라 변경되는이 제한은 동적 입니까 (즉, 사용되는 총 4 기가 바이트 둘 다, 그래서 프로그램이 스택 만 사용한다면 4 기가 바이트의 스택을 가질 수 있습니까?)

질문 2 : 한도는 어떻게 정의됩니까? 사용 가능한 총 RAM 메모리입니까?

질문 3 : 텍스트 (코드)와 데이터 섹션은 어떻게 제한됩니까?


답변:


23

두 가지 메모리 제한이 있습니다. 가상 메모리 제한 및 실제 메모리 제한

가상 메모리

가상 메모리는 사용 가능한 주소 공간의 크기와 레이아웃에 따라 제한됩니다. 일반적으로 맨 처음에는 실행 코드와 정적 데이터가 있고 힙이 커지는 과거가 있고 마지막에는 커널이 공유 라이브러리와 스택 (대부분의 플랫폼에서 아래로 자라기) 전에 예약 된 영역입니다. 이를 통해 힙 및 스택 여유 공간을 늘릴 수 있으며 다른 영역은 프로세스 시작시 알려지고 고정됩니다.

사용 가능한 가상 메모리는 처음에는 사용 가능한 것으로 표시되지 않지만 할당 중에는 표시됩니다. 힙은 사용 가능한 모든 메모리로 커질 수 있지만 대부분의 시스템은 스택을 자동 증가시키지 않습니다. 스택의 IIRC 기본 제한은 Linux의 경우 8MiB이고 Windows의 경우 1MiB이며 두 시스템에서 모두 변경할 수 있습니다. 가상 메모리에는 메모리 매핑 파일 및 하드웨어도 포함됩니다.

스택이 (임의로) 자동으로 성장할 수없는 한 가지 이유는 멀티 스레드 프로그램이 각 스레드마다 별도의 스택을 필요로하므로 결국 서로의 방식으로 들어가기 때문입니다.

32 비트 플랫폼에서 총 가상 메모리 양은 4GiB이며, Linux와 Windows는 일반적으로 커널에 마지막 1GiB를 예약하여 최대 3GiB의 주소 공간을 제공합니다. 완전한 4GiB를 제공하는 것을 예약하지 않은 특별한 Linux 버전이 있습니다. 드문 경우에 마지막 1GiB가 하루를 저장하는 대규모 데이터베이스의 경우 유용하지만 정기적 인 사용의 경우 추가 페이지 테이블 다시로드로 인해 약간 느려집니다.

64 비트 플랫폼에서 가상 메모리는 64EiB이며 이에 대해 생각할 필요가 없습니다.

물리적 메모리

실제 메모리는 일반적으로 프로세스가 액세스해야하는 경우에만 운영 체제에 의해 할당됩니다. 프로세스가 사용하는 실제 메모리의 양은 매우 모호합니다. 일부 메모리는 프로세스 (코드, 공유 라이브러리 및 기타 매핑 된 파일)간에 공유되고 파일의 데이터는 요청시 메모리에로드되어 메모리 부족이 발생하면 삭제됩니다. "익명"메모리 (파일이 지원하지 않는 메모리)가 교체 될 수 있습니다.

Linux에서 실제 메모리가 부족할 때 발생하는 상황은 vm.overcommit_memory시스템 설정 에 따라 다릅니다 . 기본값은 오버 커밋입니다. 시스템에 메모리 할당을 요청하면 일부 메모리가 제공되지만 가상 메모리 만 할당됩니다. 실제로 메모리에 액세스하면 사용할 실제 메모리를 가져 와서 다시 읽을 수있는 데이터를 삭제하거나 필요에 따라 데이터를 교체합니다. 그것이 아무것도 확보 할 수 없다는 것을 발견하면 프로세스를 존재에서 제거 할 것입니다 (반응에는 더 많은 메모리가 필요할 수 있으며 끝없는 루프로 이어질 수 있기 때문에 반응 할 방법이 없습니다).

이것이 안드로이드에서 프로세스가 죽는 방식입니다 (리눅스이기도합니다). 로직은 프로세스가 수행하는 작업과 오래된 프로세스에 따라 존재하지 않는 프로세스 로 개선되었습니다 . 안드로이드 프로세스는 단순히 아무것도하지 않지만 백그라운드에 앉아 있고 "메모리 부족"은 새로운 메모리를 필요로 할 때 프로세스를 종료시킵니다.


9

메모리가 사용되는 순서에 따라 대답하는 것이 더 쉽다고 생각합니다.

질문 3 : 텍스트 (코드)와 데이터 섹션은 어떻게 제한됩니까? 텍스트와 데이터는 컴파일러에서 준비합니다. 컴파일러의 요구 사항은 액세스 할 수 있는지 확인하고 주소 공간의 아래쪽에 압축해야합니다. 액세스 가능한 주소 공간은 하드웨어에 의해 제한됩니다. 예를 들어 명령 포인터 레지스터가 32 비트이면 텍스트 주소 공간은 4GiB입니다.

질문 2 : 한도는 어떻게 정의됩니까? 사용 가능한 총 RAM 메모리입니까? 텍스트와 데이터 뒤에는 그 위의 영역이 힙입니다. 가상 메모리를 힙는 실질적으로 성장할 수있는 최대 가까운 최대 주소 공간.

질문 1 : 스택과 힙에 정적 크기 제한 (예 : 각각 2GB)이 있거나 프로그램 실행 중 메모리 할당에 따라 변경되는 동적 한계입니까 (예 : 총 4GB) 둘 다, 그래서 프로그램이 스택 만 사용한다면 4 기가 바이트의 스택을 가질 수 있습니까?) 프로세스 주소 공간의 마지막 세그먼트는 스택입니다. 스택은 주소 공간의 끝 세그먼트를 가져오고 끝에서 시작하여 아래로 커 집니다.

힙이 커지고 스택이 커지기 때문에 기본적으로 서로를 제한합니다. 또한 두 세그먼트 유형 모두 쓰기 가능하기 때문에 세그먼트 중 하나가 경계를 넘지 않는 것이 항상 위반 인 것은 아니므로 버퍼 또는 스택 오버플로가 발생할 수 있습니다. 이제는 이런 일이 발생하지 않도록하는 메커니즘이 있습니다.

시작할 각 프로세스마다 힙 (스택)에 대한 제한이 설정되어 있습니다. 이 제한은 brk () / sbrk ()를 사용하여 런타임에 변경할 수 있습니다. 기본적으로 프로세스에 더 많은 힙 공간이 필요하고 할당 된 공간이 부족하면 표준 라이브러리가 OS에 대한 호출을 발행합니다. OS는 일반적으로 프로그램이 사용할 수 있도록 사용자 라이브러리에 의해 관리되는 페이지를 할당합니다. 즉, 프로그램이 1 KiB를 원할 경우 OS는 추가로 4 KiB를 제공하고 라이브러리는 프로그램에 1 KiB를 제공하고 다음에 프로그램이 더 많은 시간을 요청할 때 3 KiB를 남겨 둡니다.

레이아웃의 대부분은 텍스트, 데이터, 힙 (증가), 할당되지 않은 공간 및 마지막으로 스택 (증가)입니다. 그들은 모두 같은 주소 공간을 공유합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.