RAM의 공간이 한정되어 있어서 비교적 용량이 많은 보조기억장치의 영역을 메모리처럼 사용하는 개념이다.
RAM에서 처리 가능한 용량보다 더 많은 데이터를 처리해야 될경우 사용된다.
RAM에서 메모리 공간을 할당해 사용하는 방식과 다르게, 미리 필요한 가상 메모리 영역을 예약한 뒤 할당해 사용한다.
RAM은 연속적인 공간을 사용하기 때문에 메모리 할당을 바로 해도 문제가 없지만, SSD는 연속된 주소 중간에 어떤 파일이 있을지 모르기 때문에 크기를 예약하고 사용한다.
다음과 같은 코드가 이미 작성 되어 있다고 가정한다.
struct FMatrix{
union{
float m[4][4];
};
};
FMatrix* matrix = new FMatrix[128];
int count = 0;
for (int m = 0; m < 128; m++) {
for (int row = 0; row < 4; row++) {
for (int col = 0; col < 4; col++) {
matrix[m].m[row][col] = count++;
} // for(col)
} // for(row)
} // for(m)
4x4 크기의 float 배열을 원소로 하는 FMatrix 구조체를 만들어서, matrix라는 이름으로 동적 할당 하고 순서대로 값을 채워 넣은 동작이다.
우리는 가상 메모리 영역을 사용할 것이기 때문에 예약을 먼저 해야한다.
가상 메모리 사용에는 VirtualAlloc()함수가 사용된다.
VirtualAlloc()의 Parameter
- LPVOID자료형의 lpAddress : 할당할 지역의 시작 주소이다.
- SIZE_T자료형의 dwSize : 사용할 메모리 크기를 입력받는다.
- DWORD자료형의 flAllocationType : 메모리 할당 유형이다.
- DWORD자료형의 flProtect : 할당할 페이지 영역에 대한 메모리 보호상태이다.
더 자세한 내용은 Microsoft 공식문서에서 확인할 수 있다.
예시)
void* p = VirtualAlloc(nullptr, sizeof(FMatrix) * 128, MEM_RESERVE, PAGE_READWRITE);
어디가 시작인지 모르지만(nullptr) 가상 메모리로 사용할 공간(sizeof(FMatrix) * 128)만큼의 메모리를 예약하겠다(MEM_RESERVE). 그리고 이 영역은 읽고 쓰기 모두 가능하게 하겠다(PAGE_READWRITE). 라는 의미이다.
현재는 RAM에 있는 데이터를 가상 메모리로 복사하는 작업을 한다.
for (int i = 0; i < 128; i++) {
void* temp = (BYTE*)p + sizeof(FMatrix) * i;
// 가상 메모리는 BYTE 단위로 다루기 때문에 시작 위치인 p에 FMatrix 크기 * index로 주소를 할당한다.
VirtualAlloc(temp, sizeof(FMatrix), MEM_COMMIT, PAGE_READWRITE);
memcpy_s((BYTE*)temp, sizeof(FMatrix), &matrix[i], sizeof(FMatrix));
}
이번에 사용된 VirtualAlloc() 함수에서 3번째 Argument에 "MEM_COMMIT"을 입력했다. 이것은 가상 메모리의 예약한 공간에 할당을 하겠다는 의미이다.
memcpy_s() 함수를 이용해 temp의 공간에 matrix의 값을 복사하는 작업을 데이터 수(128 번)만큼 진행한다.
모든 작업이 끝난 후 RAM 영역에 선언이 되어있던 matrix 영역 할당을 해제해서 가상메모리 이외의 자원을 반환한다.
delete[] matrix; // 배열일 경우 가장 앞의 하나만 지워지기 때문에 delete에도 배열을 붙임
matrix = nullptr;
가상메모리 영역도 전부 사용한 뒤 반환을 하지 않으면 메모리의 영역을 차지하고 있기 때문에 모든 사용이 종료된 후 자원을 반환 해야한다.
메모리 할당을 해제할 때 VirtualFree()함수를 사용한다.
VirtualFree()의 Parameter
- LPVOID자료형의 lpAddress : 할당된 가산메모리 영역의 기본 주소(시작 주소)이다.
- SIZE_T자료형의 dwSize : 할당 해제할 메모리 영역의 크기이다.
- DWORD자료형의 dwFreeType : free 작업의 유형이다.
더 자세한 내용은 Microsoft 공식문서에서 확인할 수 있다.
전체 영역에 대한 할당 해제 코드는 다음과 같다.
VirtualFree(p, 0, MEM_RELEASE);
일부 영역에 대한 할당 해제 코드는 다음과 같다.
void* temp2 = (BYTE*)p + sizeof(FMatrix) * 64;
VirtualFree(temp2, sizeof(FMatrix) * 64, MEM_DECOMMIT);
원하는 크기의 영역 만큼 할당 해제한다.