2010-08-03 3 views
0

스택 및 동적 메모리 할당에 관한 질문이 있습니다.동적 메모리 할당에 관한 질문

1) 커널은 런타임 중에 스택의 크기를 동적으로 결정합니까? 아니면로드 시간 전에 크기를 설정합니까? 스택 크기가 동적으로 할당되는 경우 스택 오버플로가 발생할 수있는 방법 (스택 크기가 한계를 초과하면 페이지 처리기가 스택을 늘릴 공간을 할당하므로). 또한 동적으로 할당 된 경우 스택이 더 높은 주소에서 더 낮은 주소로 증가 할 수 있습니다 (동적 할당 저장소의 경우 항상 가상 주소가 증가하기 때문에)

2) 또한 메모리가 malloc을 사용하여 동적으로 할당되는 경우 데이터 영역의 크기가 커집니다 ?

감사 & 감사합니다,

쥐의.

답변

3

1) OS에 따라 다르지만 ty pical scheme은 운영체제가 스택에 대해 한 페이지의 가상 메모리 (페이지는 일반적으로 4KB)를 부여한 다음 가상 메모리 페이지를 "가드 페이지"로 표시 한 직후에 표시합니다. 이것은 응용 프로그램이 쓰기를 시도 할 때 저레벨 예외를 발생시키는 특수 플래그입니다.

가드 페이지에 쓰기를 시도하면 OS가 예외를 처리하고 (초기 할당 크기를 초과하여 스택이 커질 때 발생 함) 해당 페이지를 할당 (즉, 실제 메모리 페이지에 매핑)하고 오류가 발생한 쓰기가 발생한 명령어에서 프로그램을 재실행합니다. 페이지가 실제 메모리로 백업되었으므로 이번에는 작동합니다.

특정 지점 (일반적으로 1MB)이 지나면 OS는이 작업을 중지하고 스택 오버플로 예외를 트리거합니다. 이것은 일반적으로 프로그램 오류를 나타내는 것이므로 거대한 스택이 필요한 코드는 스택 데이터가 힙에 무엇이든간에 메모리를 할당 할 수 있습니다.

2) 데이터 세그먼트가 실제로 성장하지 않습니다. 현대 프로그램에는 고정 가상 메모리 주소 공간이 있습니다. malloc()은 실제 메모리와 함께이 공간과 뒤 부분을 조각하기 위해 어떤 스키마를 사용합니다.

두 질문 모두 OS가 프로그램에 실제 메모리를 제공하는 방법을 더 잘 이해하고자한다고 생각합니다.현대 시스템의 핵심 개념은 가상 메모리입니다. Wikipedia's page on virtual memory은 좋은 출발점입니다.

자세한 지식을 얻으려면 OS 교과서를 시작하는 것이 좋습니다. 가급적이면 내가 대학에서 OS 과정을 수강했을 때 가지고있는 것보다 낫다. :)

+0

답장을 보내 주셔서 대단히 감사합니다. 또한 malloc이 스왑 공간에 공간을 할당한다고 말하는 OS 책을 읽으므로 다른 방식으로 질문을했습니다. – mousey

+0

"malloc"은 물리적 메모리를 프로세스에 매핑하지 않고 malloc이 반환 한 메모리에 커널이 쓰기 만하면 커널이 처리합니다. 직접 실험 해 볼 수 있습니다. 수백 메가의 malloc을 사용하더라도 실제 RAM의 사용량은 증가하지 않습니다. –

+0

@Dietrich 그래서 내 가상 주소로 매핑해야합니까? 다른 현명한 프로그램은 효과가 없습니다! – mousey

0

1) 동적 메모리 할당은 스택이 아니라 힙에서 할당됩니다. 스택은 함수 호출 중 지역 변수 및 반환 주소도 처리하는 메모리 당 스레드 블록입니다. 힙은 OS에서 할당 된 하나 이상의 메모리 블록이며 C RTL은 malloc 호출을 충족시키는 데 필요한만큼 세분화됩니다.

스택의 경우 일반적으로 고정 크기입니다. 무한 재귀가없는 프로그램에서 한정된 양만 필요하기 때문입니다. 재귀를 계속하면 오버플로가됩니다. 이는 깨끗한 실패라는 점에서 좋은 점입니다. 메모리가 늘어남에 따라, 이는 CPU의 구현 세부 사항입니다.

2) 필수는 아닙니다. OS에서 현재 메모리를 할당하는 것만으로 충분하다면 malloc은이를 사용합니다. 일단 이것이 사라지면 추가 할당이 발생할 수 있습니다.

여기서 자세히 알고 싶지만 유용하지는 않은 것으로 알고 있습니다. 힙이 일반적으로 자유 블록의 링크 목록으로 구현되는 방식에 대해 이야기 할 수 있습니다. 크기를 정의하는 아레나 헤더를 사용하거나 일부 시스템에서 조각화를 제한하기 위해 고정 할당 크기의 블록을 사용하는 방법 또는 메모리 조각이 하나도 없을 때 병합되는 방법 충분히 큰 블록이 발견됩니다. 그러나이 모든 것은 구현 세부 사항으로, 적어도 정확히는 귀하의 경우에는 적용되지 않을 수 있습니다.

+0

1) C 동적 메모리 할당에 대해 묻지 않는다! 문제는 커널이 스택을 할당하는 방법에 관한 것입니다. 커널은 스택의 크기를 어떻게 알 수 있습니까? 2) 자세한 내용을 pls로 설명 할 수 있습니까? – mousey

+0

1) 일반적인 방법은 스레드가 스택으로 사용할 고정 된 메모리 블록을 할당하는 것입니다. –

+0

모든 스레드에 대해 스택 크기가 동일합니까? 이것은 공간의 낭비입니까? – mousey

1

스택 스레드가 생성 될 때마다 나사 고정 스택을 가지며, 일반적

크기. ulimit -a을 실행하여 시스템의 기본 스택 크기를 확인하십시오. 내 시스템에서는 8 MiB입니다. 새 스레드를 만들 때 더 작거나 큰 스택을 제공 할 수 있습니다 (pthread_attr_setstacksize 참조).

스택이 8 MiB 이상으로 커지면 프로그램은 잘못된 메모리 위치에 쓰고 충돌합니다. 커널은 스택 옆의 메모리 위치가 모두 유효하지 않도록하여 스택 오버플로시 프로그램이 중단되도록합니다.

당신은 고정 된 크기가 낭비라고 생각 할 수 있지만, 8 MIB는 가상 메모리하지 물리적 메모리입니다. 차이점은 중요합니다 (아래 참조). UNIX 시스템

MALLOC

는 메모리 할당은 두 개의 층을 갖는다. 사용자 공간 계층은 malloc (및 calloc, realloc, free)입니다.이것은 C 라이브러리의 일부이며, 여러분의 코드로 대체 될 수 있습니다 - Firefox는 이것을 수행하며, 많은 프로그래밍 언어는 malloc이 아닌 자신의 할당 체계를 사용합니다. 다양한 malloc 구현은 크로스 플랫폼입니다.

하위 계층은 mmap (및 sbrk)입니다. mmap 함수는 프로그램의 주소 공간을 변경하는 시스템 호출입니다. 그것이 할 수있는 일 중 하나는 프로그램의 메모리에 새로운 익명의 개인 페이지를 추가하는 것입니다.

malloc의 목적은 mmap (또는 sbrk)을 사용하여 커널에서 많은 양의 가상 메모리를 가져 와서 효율적으로 프로그램에 맞게 나누는 것입니다. mmap 시스템 호출은 4 KiB (대부분의 시스템에서)의 배수에서만 작동합니다.

메모리 : 실제

대 가상은 mmap에 의해 반환 된 메모리의 스택과 모든 단지 가상 메모리, 물리적 인 RAM 것을 기억하십시오. 커널은 실제 RAM을 사용할 때까지 실제 RAM을 프로세스에 할당하지 않습니다.

커널에서 익명 메모리를 얻으면 힙이나 스택에서 0으로 채워집니다. 그러나 수십 페이지의 물리적 RAM을 사전에 0으로 채우지 않고 커널은 모든 가상 메모리를 물리적 RAM의 단일 페이지로 공유합니다. 가상 메모리는 읽기 전용으로 표시됩니다. 쓰기 만하면 CPU가 예외를 던지고 커널에 제어권을 넘겨주고 커널은 프로그램에 대해 쓰기 쉽고 0 인 새로운 페이지를 할당합니다.

이는 이유를 설명 :

  • calloc보다 빠른 malloc + memset (callocmmap 'D 페이지를 미리 제로화 것을 알고 있으며, memset 물리적 RAM의 할당 강제 때문에)
  • 당신은 할 수 있습니다 RAM + 스왑 결합보다 훨씬 많은 메모리를 할당하십시오. (쓰기 전까지는 사용되지 않기 때문에)
+0

@Dietrich malloc이 sbrk 또는 mmap을 사용할 때마다 메모리가 어느 영역에 연결되어 있습니까? (데이터, 스택 또는 텍스트). 답장을 보내 주셔서 대단히 감사합니다. 데이터가 맞아야합니까? – mousey

+0

흥미 롭지 만 이것의 대부분은 유닉스에만 적용됩니다. –

+0

@Steven Windows는 지역을 구별하지 못합니까? 일반적으로 실행 파일 (Windows의 PE)에서 수행됩니다. 따라서 시스템은 제한 사항을 적용 할 수 있습니다 (예 : 텍스트 또는 코드를 읽기 전용으로 표시하거나 특정 지역을 넘어 시스템이 예외를 표시하는 경우) – mousey