본문 바로가기

3.구현/VC++

프로그램의 메모리 사용량 측정하기

프로그램 자신의 사용하고 있는 메모리 사용량을 측정하기 위한 것입니다. 다른 프로세스에 적용되지는 않습니다. 이곳에서 사용되는 방법은 VirtualQuery() 함수를 사용한 방법입니다. 생각보다 코드는 단순합니다.

작성일: 2009.10.07 (http://ospace.tistory.com/), ospace114@empal.com

메모리 사용량 측정하기

GetPrivateBytes() 함수가 메모리 사용량을 측정하는 함수이다. 이 함수는 순수하게 물리 메모리에 적재된 Private 영역만 추출하게 된다. 가상 메모리 시작은 0부터 시작해서 0x8000000까지 조회한다. 이 영역은 메모리 영역에서 프로세스 영역으로 사용자가 사용할 수 있는 Private 영역에 해당한다. 이는 Windows 98과 ME에서 제공된다. Windows 2000에서는 0xBFFF0000까지 인데 직접 테스트해보지 않아서 잘될지는 모르겠다.

반환되는 값이 메모리 사용량이 된다. 0이 반환된다면 문제가 있다는 것이겠지요.

SIZE_T GetPrivateBytes()
{
    SIZE_T x = 0;
    MEMORY_BASIC_INFORMATION memInfo;
    SIZE_T vAddress = 0;
    ZeroMemory(&memInfo, sizeof(memInfo));
    while (vAddress < (SIZE_T) 0x8000000 && VirtualQuery((LPCVOID)vAddress, &memInfo, sizeof(memInfo))) {
        if (memInfo.State == MEM_COMMIT && memInfo.Type == MEM_PRIVATE) {
            x += memInfo.RegionSize;
        }
        vAddress += memInfo.RegionSize;
    }
    return x;
}

위의 코드는 외국 어느 사이트에서 가져왔는데, 지금 찾으려고 하니깐 어딘지 모르겠다. ㅡ.ㅡ;

미리 적어두어야 하는데 아직 익숙하지 않는 모양이다.

VirtualQuery() 함수

이 함수는 호출하는 프로세스의 가상 주소 영역에 있는 페이지 범위에 대한 정보를 제공한다. 다른 프로세스의 정보를 얻고 싶다면 VirtualQueryEx()함수를 사용하면 된다.

DWORD VirtualQuery(
  LPCVOID lpAddress,
  PMEMORY_BASIC_INFORMATION lpBuffer,
  SIZE_T dwLength
);

첫 번재 인자는 질의하는 페이지 영역의 기본 주소 포인터이다. 호스트 PC의 페이지 크기을 알고 싶다면 GetSystemInfo() 함수를 사용하면 된다. 두 번째 인자는 MEMORY_BASIC_INFORMATION 구조체로 특정 페이지 범위에 대한 값이 저장되어져 반환된다. 세 번째 인자는 두 번째 인자인 MEMORY_BASIC_INFORMATION 구조체 크기을 입력한다.

제대로 수행되었다면 획득한 정보 버퍼에 대한 크기(바이트)가 리턴된다. 만약 커널 모드에 대한 포인터라면 보안상 이유로 정보도 반환되지 않으며 0을 리턴하게 될 것이다.

결론

메모리 사용량 측정은 실제 사용량 외에 메모리 릭 발생 여부 등과 같이 메모리에 관련된 다른 여러가지 일도 다룰 수 있다. 추가 VirtualQuery() 함수는 DLL Injection등 인젝션 관련된 곳에서 사용가능한 함수이다.

사실 필자는 인젝션을 잘 알지 못한다. 아직 굳이 공부할 필요는 없다고 느끼는 것인지도. 물론 대충 예전에 봤지만 실제 사용을 해봐야 알 수 있을 것 같다.

가끔씩 느끼는 것이지만, 세상에는 정말 고수가 많다. ospace.

참조

[1] VirtualQuery Funciton, http://msdn.microsoft.com/en-us/library/aa366902(VS.85).aspx, MSDN

[2] furyheimdall, 윈도우 메모리 구조, http://furyheimdall.tistory.com/34

반응형