2014-01-14 4 views
5

나는 이것이 어리석은 질문 인 것을 안다. 그러나 나는 잠시 동안 찾고 있었고 결정적인 대답을 찾을 수 없었다. mmap 또는 malloc (Linux 컴퓨터의 C 언어)을 사용하면 둘 중 하나가 RAM에 공간을 할당합니까? 예를 들어 RAM이 2GB이고 사용 가능한 모든 RAM을 사용하려는 경우 malloc/memset 콤보, mmap을 사용할 수 있습니까, 아니면 모를 다른 옵션이 있습니까?mmap 또는 malloc이 RAM을 할당합니까?

동시에 실행될 수있는 일련의 간단한 프로그램을 작성하고 프로세스에서 사용되는 모든 RAM을 사용하여 스왑이 사용되도록하고 페이지를 빈번하게 스왑/아웃합니다. 나는 아래의 프로그램으로 이것을 이미 시도했지만, 그것이 내가 원하는 것만은 아니다. 메모리 (RAM?)를 할당하고 강제 스왑을 사용합니다 (충분한 인스턴스가 실행중인 경우). 그러나 sleep을 호출하면 메모리가 사용되지 않도록 잠글 수 없습니다 (아무 것도 실제로 스왑되거나 스왑되지 않음). 다른 프로세스?), 또는 나는 뭔가를 오해하고 있습니다.

예를 들어 3 번 실행하면 첫 번째 두 인스턴스에서 2GB (모두)의 RAM을 사용하게되고 세 번째 인스턴스는 이전 두 인스턴스 중 하나 (RAM)를 바꿔 현재 RAM에 인스턴스? 아니면 인스턴스 # 3은 디스크 또는 가상 메모리를 사용하여 실행됩니까?

또 다른 점이 있습니다. 스왑 파티션을 사용할 수 있도록 모든 사용 가능한 가상 메모리를 사용할만큼 충분한 메모리를 할당해야합니까?

마지막으로 mmap (또는 다른 C 함수. 지옥, 해당되는 경우 다른 언어)이 작업을 수행하는 것이 더 좋을까요?

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

#define MB(size) ((size) * 1024 * 1024) 
#define GB(size) ((size) * 1024 * 1024 * 1024) 


int main(){ 
    char *p; 
    p = (char *)malloc(MB(512)); 
    memset(p, 'T', MB(512)); 
    printf(".5 GB allocated...\n"); 

    char *q; 
    q = (char *)malloc(MB(512)); 
    memset(q, 'T', MB(512)); 
    printf("1 GB allocated...\n"); 
    printf("Sleeping...\n"); 

    sleep(300); 
} 

** 편집 : 내 OS 용 CentOS 6.4 (3.6.0 커널 포함)를 사용하고 있습니다.

+0

나는 문서에서 말한 것처럼 프로세스의 가상 주소 공간을 RAM에 잠글 수 있다고 말하는'mlock()'이나'mlockall()'을 제안 할 것이다. – Macattack

+0

OS 의존적이지만 OS가 우선 순위를 관리하기 때문에 다른 프로그램을로드 할 때 RAM이 계속 사용된다고는 생각지 못합니다. 프로그램 실행시 RAM을 사용하게되고 나머지는 스왑으로 바뀝니다 –

+0

여기에 설명이 있습니다. 자세한 내용을 보려면 http://stackoverflow.com/questions/2688466/why-mallocmemset-is-slower-than-calloc/2688522#2688522 [1] : http://stackoverflow.com/question/2688466/why-mallocmemset-is-calloc/2688522 # 2688522 – Alex

답변

9

이것은 매우 OS/기계에 따라 다릅니다.

대부분의 OS에서는 RAM을 할당하지 않습니다. 둘 다 VM 공간을 할당합니다. 프로세스의 특정 범위의 가상 메모리를 사용할 수 있도록합니다. RAM은 일반적으로 첫 번째 쓰기에서 OS에 의해 나중에 할당됩니다. 그때까지 이러한 할당은 RAM을 사용하지 않습니다 (유효한 VM 공간으로 나열된 페이지 테이블 제외).

실제 RAM을 할당하려면 각 페이지 (sysconf(_SC_PAGESIZE)은 시스템 페이지 크기를 제공)를 더럽혀 야합니다.

리눅스에서는 모든 세부 사항이 /proc/self/smaps 인 VM 매핑을 볼 수 있습니다. Rss은 해당 매핑의 상주 세트 (RAM에있는 용량)이며, 더티 인 것은 모두 스왑 아웃됩니다. 더티가 아닌 메모리는 모두 사용할 수 있지만 그때까지는 존재하지 않습니다.

당신은 그냥 ENOMEMmmap 실패 할 수 있습니다 이것은 또한 mmapMAP_POPULATE 플래그를 전달하지만, (시스템에 따라 다름)에 의해 달성 될 수있는 몇 가지 구현에

size_t mem_length; 
char (*my_memory)[sysconf(_SC_PAGESIZE)] = mmap(
     NULL 
    , mem_length 
    , PROT_READ | PROT_WRITE 
    , MAP_PRIVATE | MAP_ANONYMOUS 
    , -1 
    , 0 
    ); 

int i; 
for (i = 0; i * sizeof(*my_memory) < mem_length; i++) { 
    my_memory[i][0] = 1; 
} 

처럼 뭔가 모든 페이지가 더러운 할 수 있습니다 만약 당신이 더 많은지도를하려고한다면 당신은 RAM을 사용할 수 있습니다.

+0

스왑의 헤더 형식은 무엇입니까? 예를 들어, 첫 번째 줄은 "00400000-0040b000 r-xp 00000000 fd : 00 1048608"입니다.이 처음 두 개는 실제 메모리의 시작/끝 주소라고 가정합니다. 그렇다면 나머지는 무엇입니까? – cHam

+0

@cHam 모든 주소는 VM 주소입니다. 시간이 지남에 따라 변할 수있는 물리적 주소는 어디에도 없습니다. 'r-xp'는 권한 (이 경우 읽기/실행/개인)입니다. 0은 기본 매핑 파일 (해당되는 경우)의 오프셋, 기본 파일/장치 매핑의 장치 설명 자입니다. 마지막으로 매핑 된 장치의 inode이며 적용 할 수없는 경우 0입니다. 자세한 내용은 http://linux.die.net/man/5/proc를 참조하십시오. –

+0

각 페이지를 더럽게 만드는 방법에 대한 제안 사항이 있습니까? (sysconf (_SC_PAGESIZE))와 함께해야 할 일이 무엇인지 모르겠습니다 ... – cHam

4

여기에서는 이론과 실습이 크게 다릅니다. 이론적으로는 mmap이나 malloc은 실제 RAM을 할당하지 않지만 실제 RAM은 할당합니다.

mmap은 가상 메모리 영역 데이터 구조 (VMA)를 저장하기 위해 RAM을 할당합니다.매핑 할 실제 파일과 함께 mmap을 사용하면 매핑 된 파일의 내용을 미리 가져 오기 위해 여러 페이지의 RAM을 더 할당합니다.
그 외의 경우에만 주소 공간을 예약하고 RAM은 처음 액세스 될 때 할당됩니다.

malloc 유사하게, 논리적으로 만 보유 중 sbrk 또는 주소의 일부 (당신이 요청보다 일반적으로 훨씬 더 큰) 영역을 관리하고자하는 mmap를 통해 운영 체제를 말하는하여 프로세스의 가상 주소 공간 내에서 주소 공간의 양 공간. 그런 다음 다소 복잡한 알고리즘을 통해이 거대한 영역을 세분화하고 마지막으로이 주소 공간의 일부를 사용하기 위해 적절히 정렬하고 반올림하여 포인터를 반환합니다.
그러나 :malloc도 어딘가에 추가 정보를 저장해야하거나 나중에 free이 작업을 수행 할 수 없습니다. 최소한 free은 시작 주소 외에 할당 된 블록의 크기를 알아야합니다. 일반적으로 malloc은 비밀리에 사용자가받는 주소 바로 앞에 몇 개의 여분의 바이트를 할당합니다. 당신은 그 사실을 모릅니다.

지금 문제의 핵심 이론 malloc에서 그것이 실제로 을 관리하고 물리적 RAM을 할당하지 않는 메모리에 닿지 않도록하면서을 수행한다는 것이다. 그리고 이것은 실제로 페이지 폴트 및 메모리 페이지가 생성되도록한다 (즉, RAM이 사용됨).
리눅스에서는 malloc으로 전화를 걸어 볼 수 있으며 실제로 으로 남아 있어야 시스템에 실제 RAM이 부족하기 때문에 OOP 킬러가 프로세스를 중단시키는 것을 볼 수 있습니다.