가상 메모리
- 물리적인 메모리(RAM)와 하드디스크의 페이징 파일 합한 것
- 사실 페이징 파일은 물리적인 RAM과 논리적으로는 동일하되 다만 속도가 좀 느린 메모리
- 응용 프로그램 입장에서 볼 때 자신의 주소 공간에 연결된 가상 메모리가 물리적인 RAM인가 페이징 파일인가는 전혀 신경쓰지 않음
- 운영체제의 안정성에도 큰 역할
- 각 프로세스의 주소 공간은 상호 독립적이기 때문에 프로세스 끼리 서로의 주소 영역을 침범할 수 없다
- 운영체제는 프로세스가 생성될 때마다 독립적인 4G 바이트의 주소 공간을 생성하고 물리적인 메모리를 논리적인 주소 공간에 연결
- 물리적인 메모리와 논리적인 주소 공간의 대응관계는 페이지 테이블이라는 표에 작성
- 페이지 테이블에는 가상메모리의 어디쯤이 응용 프로그램의 누구의 몇 번지에 연결되어 있다는 정보가 기록
- 응용 프로그램은 오로지 자신의 주소 공간 상의 번지만 다룸
- 프로세스는 자신에게 주어진 4G의 가상 주소 공간이 실제의 메모리인 것 처럼 사용
- 주소 공간 : 이 페이지 테이블에 기록 되어 있는 응용 프로그램이 참조하는 주소값
- 가상 주소 공간 : 실제로 존재하는 메모리가 아니라 다만 페이지 테이블에 기록되는 개념적인 주소
* 핵심은 모든 그리는 것을 비트맵에 그리고 나중에
화면에 결과 비트맵을 보여준다
기존 DC 와 호환되는 Memory DC를 생성하고 거기에 비트맵을 선택하여
Memory DC를 이용하여 그림을 그린 다음
Bitmap을 기존 DC를 이용하여 그려준다
다시 순서를 정리하면
1. 기존 DC와 호환되는 Memory DC 객체 생성 - CreateCompatibleDC( );
2. 기존 DC와 호환되는 비트맵 객체 생성 - CreateCompatibleBitmap( );
3. 메모리 DC가 비트맵 객체를 선택 - SelectObject( )
4. 메모리 DC를 가지고 그림을 그림 - MoveTo, LineTo, Ellipse, Rect 등등
5. 비트맵 객체를 기존 DC를 가지고 그려줌 - BitBlt( )
6. 메모리 객체 해제
void CView::OnPaint(CDC* pDC)
{
// 1. memDC 객체 생성
CDC memDC;
memDC.CreateCompatibleDC(pDC);
// 2. 메모리 비트맵 생성
CRect rect;
GetClientRect(rect);
CBitmap bitmap;
bitmap.CreateCompatibleBitmap(pDC, rect.Width(), rect.Height());
// 3. 메모리 DC 가 메모리 비트맵 선택
CBitmap* oldmap = memDC.SelectObject(&bitmap);
// 4. 그려주기
memDC.MoveTo(0, 0);
memDC.LineTo(100, 100);
// 5. 그려주기
pDC->BitBlt(0, 0, rect.Width(), rect.Height(), &memDC, 0, 0, SRCCOPY);
// 6. 메모리 객체 해제
memDC.SelectObject(oldmap);
memDC.DeleteDC();
bitmap.DelectObject();
}
* 더블 버퍼링
- 화면에 보여줄 버퍼와 내부 작업에 사용할 버퍼를 따로 유지
- 내부 버퍼에 미리 그림을 그린 후 화면 버퍼로 고속 전송
- 그리는 중간 과정을 숨겨진 내부 버퍼에서 처리
- 더블 버퍼링에 사용되는 내부 버퍼는 구체적으로 메모리 영역인데
이 메모리의 영역은 외부 버퍼, 즉 화면의 포맷과 호환되어야 한다
- 그래야 내부 버퍼에 그린 그림을 별도의 조작없이 외부 버퍼로 고속 전송 가능
- 윈도우즈에서는 내부 버퍼를 메모리에 직접 작성할 필요가 없는데
왜냐하면 비트맵이 내부 버퍼 역할을 멋지게 대신함
- 화면 DC 와 호환되는 비트맵(색상 포맷이 같고 크기가 동일)을 생성한 후
이 비트맵에 그림을 긜면 비트맵 자체가 내부 버퍼 역할을 함
- 비트맵에 그려진 화면을 전송할 때는 BitBlt 함수 사용
ModifyStyleEx(WS_EX_APPWINDOW, WS_EX_TOOLWINDOW);
CRect rect;
GetDesktopWindow()->GetWindowRect(rect);
MoveWindow(rect);
ShowWindow(SW_SHOWMAXIMIZED);
RedrawWindow();
- 윈도우즈에서 화면상에 무엇인가를 그리는 과정은 상상외로 복잡하다
- 대충 출력하기는 쉽지만 꼭 필요할 때 최대한 짧은 시간에 최소한의 영역만 그리면서도 깜빡임을 최소화 하는 것은 보통 어려운 것이 아니다
- 그리기를 얼마나 빠른 시간에 효율적으로 할 수 있는가에 따라 응용 프로그램의 질에 큰 차이가 나게 되므로 결코 가볍게 다룰 수 있는 주제가 아니다
- 윈도우즈에서 그리기가 복잡하고 난해한 근본적인 이유는 여러 개의 프로그램이 동시에 실행되는 멀티 태스킹 운영체제
- 윈도우즈 프로그램은 화면을 혼자서 사용하지 못하며 화면에 출력하는 것이 아니라 자신이 차지하고 있는 윈도우에 그것도 허가된 영역에만 그릴 수 있다
- 게다가 공간적으로 제약이 따를 뿐만 아니라 한 번 그려 놓은 그림이 항상 그대로 있다고 보장되지 않는 시간적 제약도 있다
- 복수 개의 프로그램이 같은 화면에 겹쳐서 공존하다 보니 서로 간에 지켜야 할 약속과 제약이 존재하고 그리는 과정도 복잡하다
- 이런 복잡한 과정을 조금이나마 단순화하기 위한 장치가 DC
- DC에는 그리기에 필요한 여러 가지 정보가 저장되어 있으며 프로그램은 DC의 정보를 참조하여 그리기를 하고 DC의 정보를 조작하여 그리는 방법을 변경
-