programing

malloc에서 할당할 수 있는 최대 메모리

nicescript 2022. 8. 9. 22:06
반응형

malloc에서 할당할 수 있는 최대 메모리

머신(1 Gb RAM 160 Gb HD Windows 플랫폼)에서 최대 메모리 용량을 파악하려고 했습니다.

malloc가 할당할 수 있는 최대 메모리는 물리 메모리(히프상의)에 한정되어 있는 것을 확인했습니다.

또, 프로그램이 메모리 소비량을 일정 레벨까지 넘으면, 다른 애플리케이션이 필요로 하는 메모리를 충분히 확보하지 못하기 때문에, 컴퓨터는 동작을 정지합니다.

그래서 확인차 작은 프로그램을 C로 작성했습니다.

int main(){  
    int *p;
    while(1){
        p=(int *)malloc(4);
        if(!p)break;
    }   
}

메모리 할당에 실패하여 루프가 끊어질 때가 오기를 바랐는데 컴퓨터가 무한 루프처럼 멈춰 버렸습니다.

나는 한 시간 정도 기다렸고 결국 컴퓨터를 강제로 꺼야 했다.

몇 가지 질문:

  • malloc도 HD에서 메모리를 할당합니까?
  • 위의 행동에 대한 이유가 무엇입니까?
  • 왜 어떤 시점에서도 루프가 끊어지지 않았을까요?
  • 왜 할당 실패가 없었습니까?

/proc/sys/vm/overcommit_memory는 Linux의합니다.

를 들어 Ubuntu 19.04에서는 를 사용하면 쉽게 구현되어 있음을 알 수 있습니다.

★★★★★★★★★★★★★★★.man proc에 어떻게 하다, 어떻게 하다, 어떻게 하다, 이렇게 요./proc/sys/vm/overcommit_memory을 제어합니다.즉, 최대 할당은 다음과 같습니다.

이 파일에는 커널 가상 메모리 계정 모드가 포함되어 있습니다.값은 다음과 같습니다.

  • 0: 경험적 오버 커밋(기본값)
  • 1: 항상 오버 커밋, 확인하지 않음
  • 2: 항상 체크하고 오버 커밋하지 않음

모드 0에서는 MAP_NORESERVE를 사용한mmap(2) 콜은 체크되지 않으며 기본 체크는 매우 약하기 때문에 프로세스가 "OOM-killed"될 위험이 있습니다.

모드 1에서는, 실제로 메모리가 부족할 때까지, 커널은 항상 충분한 메모리가 있는 것처럼 가장합니다.이 모드의 사용 예 중 하나는 대규모 스파스 어레이를 계획하는 과학 컴퓨팅 애플리케이션입니다.Linux 커널 버전 2.6.0 이전에서는 0이 아닌 값은 모드 1을 의미합니다.

모드 2(Linux 2.6 이후 사용 가능)에서는 할당할 수 있는 총 가상 주소 공간(/proc/meminfo의 CommitLimit)은 다음과 같이 계산됩니다.

CommitLimit = (total_RAM - total_huge_TLB) * overcommit_ratio / 100 + total_swap

여기서:

  • total_RAM은 시스템상의 RAM의 총량입니다.
  • 합계_total_total_syslog_TLB는 큰 페이지에 할당되어 있는 메모리의 양입니다.
  • overcommit_module은 /sys/vm/overcommit_module의 값입니다.
  • total_total은 스왑 영역의 양입니다.

예를 들어 16GB의 물리 RAM, 16GB의 스왑, 대용량 페이지 전용 공간 없음 및 50의 overcommit_ratio를 갖춘 시스템에서는 이 공식에 따라 Com† mitLimit 24GB가 생성됩니다.

Linux 3.14 이후 /proc/sys/vm/overcommit_kbytes 값이 0이 아닌 경우 Commit Limit은 대신 다음과 같이 계산됩니다.

CommitLimit = overcommit_kbytes + total_swap

/proc/sys/vm/admiin_reserve_kbytes 및 /proc/sys/vm/user_reserve_kbytes 설명을 참조하십시오.

5.2.1 커널 트리의 documentation/vm/overcommit-accounting.rst에서도 몇 가지 정보를 얻을 수 있습니다.단, lol은 조금 적습니다.

Linux 커널은 다음과 같은 오버 커밋 처리 모드를 지원합니다.

  • 0경험적 오버 커밋 처리입니다.주소 공간의 명백한 오버 커밋은 거부됩니다.표준 시스템에 사용됩니다.는 이 할 수 있습니다.root은 모드에서 를 약간 더 할당할 수 .이것이 기본값입니다.

  • 1항상 오버 커밋합니다.일부 과학 분야에 적합합니다.전형적인 예로는 스파스 어레이를 사용하여 거의 0페이지로 구성된 가상 메모리에 의존하는 코드를 들 수 있습니다.

  • 2츠미야시스템의 총 주소 공간 커밋은 물리적 RAM의 스왑 + 구성 가능한 양(기본값은 50%)을 초과할 수 없습니다.사용하는 양에 따라서는, 대부분의 경우, 페이지에 액세스 하는 동안 프로세스가 종료하는 일은 없지만, 메모리 할당에 관한 에러가 표시됩니다.

    향후 모든 페이지를 초기화하지 않고 메모리 할당을 확실하게 하고 싶은 어플리케이션에 도움이 됩니다.

최소 실험

다음과 같이 최대 허용치를 쉽게 확인할 수 있습니다.

메인

#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <string.h>
#include <unistd.h>

int main(int argc, char **argv) {
    char *chars;
    size_t nbytes;

    /* Decide how many ints to allocate. */
    if (argc < 2) {
        nbytes = 2;
    } else {
        nbytes = strtoull(argv[1], NULL, 0);
    }

    /* Allocate the bytes. */
    chars = mmap(
        NULL,
        nbytes,
        PROT_READ | PROT_WRITE,
        MAP_SHARED | MAP_ANONYMOUS,
        -1,
        0
    );

    /* This can happen for example if we ask for too much memory. */
    if (chars == MAP_FAILED) {
        perror("mmap");
        exit(EXIT_FAILURE);
    }

    /* Free the allocated memory. */
    munmap(chars, nbytes);

    return EXIT_SUCCESS;
}

GitHub 업스트림

컴파일하여 실행하여 1GiB 및 1TiB를 할당합니다.

gcc -ggdb3 -O0 -std=c99 -Wall -Wextra -pedantic -o main.out main.c
./main.out 0x40000000
./main.out 0x10000000000

그런 다음 할당 값을 사용하여 시스템이 허용하는 것을 확인할 수 있습니다.

수 .0단, 이 허용되지 않습니다 ( ) 、 32GiB RAM 、 1TiB の ( ( 。

mmap: Cannot allocate memory

그러나 무제한 오버커밋을 사용하도록 설정한 경우:

echo 1 | sudo tee /proc/sys/vm/overcommit_memory

1TiB 할당은 정상적으로 동작합니다.

" "2증명은 잘 되어 있지만, 그것을 검증하기 위해서 정확한 계산을 하는 것은 귀찮습니다..

overcommit_ratio / 100

및 RAM의 합계overcommit_ratio50【램】【램】【램】【램】【램】

VSZ 대 RSS 및 메모리 부족 문제 해결

지금까지 가상 메모리를 할당했습니다.

단, 이러한 페이지를 충분히 사용하면 Linux에서 몇 가지 프로세스를 종료해야 합니다.

Linux 메모리 관리의 RSSVSZ란?에서 자세히 설명했습니다.

내가 읽은 바로는 최대 메모리는malloc됩니다.can allocate는 물리 메모리(heap상의)로 제한됩니다.

틀렸습니다.대부분의 컴퓨터/OS는 디스크 용량으로 백업된 가상 메모리를 지원합니다.

가지 질문: "Do you does 」 、 "Does" :mallocHDD ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★」

mallocOS の os os os os 。이것에 의해, 디스크 영역이 사용되게 되는 경우가 있습니다.

위의 동작의 원인은 무엇입니까?왜 루프가 끊어지지 않았을까요?

왜 할당 실패가 없었습니까?

한 번에 너무 적게 요구하면 루프가 끊어집니다(가상 메모리와 물리 메모리의 대량 사용으로 인해 머신이 크롤링으로 느려지고 나서 디스크 액세스가 매우 빈번해지기 때문에, 「스래시」라고 불리는 문제). 하지만, 그 이전에는 인내심을 충분히 잃었습니다.대신 한 번에 1메가바이트를 얻도록 하세요.

프로그램이 메모리 사용량을 일정 수준으로 초과하면 다른 응용 프로그램이 필요한 메모리를 충분히 확보하지 못하기 때문에 컴퓨터가 작동을 중지합니다.

완전히 정지할 가능성은 낮지만, 통상 몇 마이크로초 걸리는 조작에 수십 밀리초 정도 걸리는 경우(예를 들어) 이들 4개의 매그니튜드 순서에 의해 컴퓨터가 기본적으로 정지한 것처럼 느껴질 수 있습니다.일반적으로 1분 걸리는 조작에는 1주일이 걸릴 수 있습니다.

이거 드셔보세요

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

main() {
    int Mb = 0;
    while (malloc(1<<20)) ++Mb;
    printf("Allocated %d Mb total\n", Mb);
}

및합니다.stdlib st stdio 。
이 추출물은 깊은 c비밀에서 추출한 것입니다.

이 스레드가 오래된 것은 알지만 직접 시도해보실 분은 이 코드를 사용하세요.

#include <stdlib.h>

int main() {
int *p;
while(1) {
    int inc=1024*1024*sizeof(char);
    p=(int*) calloc(1,inc);
    if(!p) break;
    }
}

달려.

$ gcc memtest.c
$ ./a.out

실행 시 이 코드는 커널에 의해 종료될 때까지1개의 RAM을 채웁니다.malloc 대신 calloc을 사용하여 "lazy evaluation"을 방지합니다.이 스레드에서 얻은 아이디어: Malloc Memory Questions

이 코드는 RAM(4Gb)을 빠르게 채우고 20Gb 스왑 파티션이 종료되기 전에 약 2분 만에 가득 찼습니다.물론 64비트 Linux.

C90 규격에 따라 32kBytes 크기의 오브젝트를 적어도1개 취득할 수 있습니다.이것은 스태틱, 다이내믹 또는 자동 메모리입니다.C99는 최소 64KB를 보증합니다.상한치에 대해서는, 사용의 컴파일러의 메뉴얼을 참조해 주세요.

또한 malloc 인수는 size_t이고 해당 유형의 범위는 [0,SIZE_MAX]입니다.따라서 요구 가능한 최대값은 SIZE_MAX 입니다.이 값은 구현에 따라 다르며 에 정의되어 있습니다.<limits.h>.

malloc는, 독자적인 메모리 관리를 실시해, 작은 메모리 블록 자체를 관리합니다만, 최종적으로 Win32 히프 기능을 사용해 메모리를 할당합니다.생각할 수 있다malloc'무슨 일이든'

Windows 메모리 서브시스템은 물리 메모리(RAM)와 가상 메모리(HD)로 구성됩니다.물리 메모리가 부족하면, 일부의 페이지를 물리 메모리에서 하드 드라이브의 가상 메모리로 카피할 수 있습니다.Windows 에서는, 이것을 투과적으로 실시합니다.

디폴트에서는, 가상 메모리는 유효하게 되어 있어, HD 의 빈 영역을 소비합니다.따라서 프로세스에 가상 메모리를 모두 할당하거나(32비트 윈도에서는 2GB) 하드디스크가 가득 찰 때까지 테스트는 계속 실행됩니다.

사실 왜 실패했는지는 모르겠지만 한 가지 주의할 점은 'malloc(4)'가 실제로는 4바이트를 제공하지 않을 수 있기 때문에 이 기술은 최대 힙 크기를 찾는 정확한 방법이 아니라는 것입니다.

여기 질문에서 이 사실을 알아냈어요

예를 들어, 4바이트의 메모리를 선언할 때 메모리 바로 앞에 있는 공간에 요청한 메모리 양을 나타내는 정수 4가 포함될 수 있습니다.

크기를 *p에 처음 할당할 때, 다음에 해당 메모리를 참조하지 않도록 할 때마다.즉,

프로그램이 4바이트의 메모리만 할당하고 있을 때

그러면 어떻게 RAM 전체를 사용할 수 있을까요?그래서 스왑 디바이스(HDD의 임시 공간)는 논의 대상에서 제외됩니다.프로그램이 메모리 블록을 참조하지 않을 때 해당 블록이 프로그램 메모리 요청에 할당될 수 있는 메모리 관리 알고리즘을 알고 있습니다.그렇기 때문에 RAM 드라이버는 계속 사용 중이며 다른 프로그램을 지원할 수 없습니다.또한 이것은 매달린 참조 문제이기도 합니다.

Ans : RAM 크기만큼 메모리를 할당할 수 있습니다.스왑 디바이스에 액세스 할 수 있는 프로그램이 없기 때문입니다.

당신의 모든 질문이 만족스러운 답변을 얻었기를 바랍니다.

언급URL : https://stackoverflow.com/questions/2798330/maximum-memory-which-malloc-can-allocate

반응형