2017-03-17 1 views
1

메모리 사용량에 대한 자세한 내용과 C++를 사용하여 측정하는 방법을 배우려고합니다. <Windows.h>을 포함 할 때 내가 Windows에서, RAM의 양을 검색하는 빠른 방법은 현재 응용 프로그램 프로세스에 의해 사용되는 것을 알고있다 :GetProcessMemoryInfo를 사용하여 정적 배열 메모리 사용을 측정 할 수 없습니다.

:

PROCESS_MEMORY_COUNTERS info; 
GetProcessMemoryInfo(GetCurrentProcess(), &info, sizeof(info)); 
(uint64_t)info.WorkingSetSize; 

다음, 나는 아주 간단한 테스트를 실행하는 사용 나는 위의 코드를 실행할 때 나는 전혀 이해하지 못하는 어떤

#include <iostream> 
#include <Windows.h>" 

int main(void) 
{ 
    uint64_t currentUsedRAM(0); 

    PROCESS_MEMORY_COUNTERS info; 
    GetProcessMemoryInfo(GetCurrentProcess(), &info, sizeof(info)); 
    currentUsedRAM = info.WorkingSetSize; 

    const int N(1000000); 
    int x[N]; //in the second run, comment this line out 
    int y[N]; //in the second run, comment this line out 
    //int *x = new int[N]; //in the second run UNcomment this line out 
    //int *y = new int[N]; //in the second run UNcomment this line out 
    for (int i = 0; i < N; i++) 
    { 
     x[i] = 1; 
     y[i] = 2; 
    } 

    GetProcessMemoryInfo(GetCurrentProcess(), &info, sizeof(info)); 
    currentUsedRAM = info.WorkingSetSize - currentUsedRAM; 

    std::cout << "Current RAM used: " << currentUsedRAM << "\n"; 

    return 0; 
} 

는, 출력은 다음과 같습니다 Current RAM used: 0, 나는 1 개 백만 항목을 각각 두 1D int 배열을 작성하기 때문에 내가 8메가바이트 주위에 뭔가를 기대하고있다. 자, 코드를 다시 실행했지만 xy을 dinamically 할당 된 배열로 만들면 이제 예상대로 결과가 출력됩니다 : Current RAM used: 8007680.

왜 그럴까요? 두 경우 모두 메모리 사용을 탐지하는 방법은 무엇입니까?

+0

두 개의 배열에 대해 스택에 거의 8 메가의 메모리를 할당했기 때문에 프로그램이 시작되는 것에 놀랐습니다. Windows의 기본 스택 크기는 대개 단일 MB입니다. 그리고 이것으로 왜 예상 결과를 얻지 못했는지에 대한 힌트를 얻어야합니다. –

+0

@Someprogrammerdude 그건 정확히 ** 의심 스러워요. 필자의 직감은 함수가 스택에서가 아니라 힙에서의 메모리 할당만을 측정한다는 것이었다. 그러나 응용 프로그램이 실행되기 때문에 어떤 일이 벌어지고 있는지 이해할 수 없었습니다. 따라서 함수가 힙 메모리 사용 만 가져옵니다. 스택 메모리 사용량을 계산하는 방법이 있습니까? –

+0

컴파일은 두 배열을 최적화했습니다. 이를 방지하기 위해 부작용을 만들 수 있습니다 : 요소의 합을 출력하십시오. – felix

답변

0

컴파일러가 코드를 최적화했습니다. 사실, 처음 실행하면 x 또는 y가 할당되지 않습니다. 보이는 부작용이 있음을 고려하면 GetProcessMemoryInfo의 반환 값인이 최적화는 이상하게 보입니다.

어쨌든이 두 어레이의 각 요소의 합계를 출력하는 등의 부작용을 추가하면 충돌을 방지 할 수 있습니다.

자동 저장 기간이있는 로컬 개체에 할당되는 메모리는 at the beginning of the enclosing code block and deallocated at the end이됩니다. 그래서 당신의 코드는 main에서 자동 sotrage 기간 변수의 메모리 사용량을 측정 할 수 없습니다 (삭제되지 않은 코드 스 니펫은 인식하지 못했습니다). 그러나 동적 저장 기간을 가진 객체의 경우에는 상황이 다르므로 요청 당 할당됩니다.


나는 논평 영역에서 토론을위한 시험을 계획했다. 프로그램이 더 깊어지면 메모리 사용량이 증가한다는 것을 알 수 있습니다. 이것은 스택상의 memroy 사용량을 계산한다는 증거입니다. BTW는 개체에 필요한 메모리의 양을 계산하지 않지만 프로그램에 필요한 메모리의 수는 계산합니다.

void foo(int depth, int *a, int *b, uint64_t usage) { 
    if (depth >= 100) 
    return ; 
    int x[100], y[100]; 

    for (int i = 0; i < 100; i++) 
    { 
    x[i] = 1 + (a==nullptr?0:a[i]); 
    y[i] = 2 + (b==nullptr?0:b[i]); 
    } 

    PROCESS_MEMORY_COUNTERS info; 
    GetProcessMemoryInfo(GetCurrentProcess(), &info, sizeof(info)); 

    std::cout << "Current RAM used: " << info.WorkingSetSize - usage << "\n"; 

    foo(depth+1,x,y,usage); 

    int sum = 0; 
    for (int i=0; i<100; i++) 
    sum += x[i] + y[i]; 

    std::cout << sum << std::endl; 
} 

int main(void) 
{ 
    uint64_t currentUsedRAM(0); 
    PROCESS_MEMORY_COUNTERS info; 
    GetProcessMemoryInfo(GetCurrentProcess(), &info, sizeof(info)); 
    currentUsedRAM = info.WorkingSetSize; 

    foo(0, nullptr, nullptr, currentUsedRAM); 

    return 0; 
} 

/* 
Current RAM used: 0 
Current RAM used: 61440 
Current RAM used: 65536 
Current RAM used: 65536 
Current RAM used: 65536 
Current RAM used: 65536 
Current RAM used: 69632 
Current RAM used: 69632 
Current RAM used: 69632 
Current RAM used: 69632 
Current RAM used: 69632 
Current RAM used: 73728 
*/ 

시스템은 매번 페이지 크기 인 4k를 할당합니다. 왜 0인지, 갑자기 61440인지 알지 못합니다. Windows가 메모리를 관리하는 방법을 설명하는 것은 매우 어렵습니다. 4k에 확신이 있지만 메모리 사용량을 계산합니다. 자동 저장 기간이있는 변수의 경우.

+0

N을 바꾸면 현재 사용되는 RAM이 변경되지 않는다고 생각합니다. 스택의 크기가 고정되어 있기 때문입니다. – felix

+0

나는 그렇게 생각하지 않는다. 루프의 반복 횟수를 1에서 스택 내에서 얻을 수있는 최대 높이 (예 : 250000)로 변경해보십시오.사용 된 RAM의 양이 변경되지 않음을 알 수 있습니다. 캡처중인 RAM은 생성 된 배열과 아무 관련이 없습니다. 배열은 모두 스택에 포함되어 있기 때문에 함수는 계산하지 않습니다. 힙 메모리 만 계산합니다. RAM 사용량은 엄청나게 비싼'std :: cout' 호출 때문에 전체 숫자입니다. 다른 모든 것을 주석으로 처리하고'std :: cout << 1 << std :: endl' 만 남겨두면 같은 RAM 사용량을 얻을 수 있습니다. –

+0

(죄송합니다. 실수로 편집을 시도하는 동안 첫 번째 주석이 지워졌습니다.하지만 위의 새로운 주석에서 볼 수 있듯이 테스트 한 결과, 내가 말한 내용에 확신을 갖게되었습니다. 볼 것이다) –

관련 문제