지난 ‘Windows 메모리 FAQ’에서 Windows 메모리에 대한 이야기를 드렸는데요, 특히 Windows 클라이언트의 4GB 제한에 대해서 여러분들의 아주 뜨거운(?) 반응이 있었습니다. 그래서 지난 번에 약속 드린 ‘Easy Transfer를 이용한 마이그레이션’은 다음 포스팅으로 미루고 오늘은 ‘4GB 제한의 진실, 32비트 Windows 클라이언트‘라는 주제로 Q&A 형식으로 이야기를 나누도록 하겠습니다.
Q1) 왜 Windows 클라이언트는 4GB까지만 지원하나요?
1. Windows XP가 처음 출시된 초기만 해도 4 기가 바이트(GB) 메모리라는 게 서버에서도 거의 사용되지 않는 고사양의 메모리였으므로 4GB를 이상 지원을 고려할 필요가 없었습니다. (당시는 일반적으로 사용하는 서버의 메모리가 512MB 혹은 그 이하였던 시절 이였습니다, 64MB 서버도… ^^)
2. Windows XP SP2가 출시될 시점에 윈도우 클라이언트도 4GB 메모리 필요성의 조짐이 보였습니다, 그래서 당시 Windows 개발팀에서는 윈도우 클라이언트에서 4GB 이상 메모리 지원을 검토하였습니다.
3. 그런데 윈도우 클라이언트에서 4GB 이상의 메모리를 관리(Memory Management)하면 블루스크린(Crash), 시스템 행(System Hang), 부팅이 되지 않거나 혹은 비디오 카드 같은 장치의 드라이버 문제로 장치를 인식하지 못하는 문제가 빈번하게 발생하는 것을 볼 수 있었습니다. (대부분 Memory corruption)
4. 원인은 윈도우 클라이언트를 위해 만들어진 3'rd Party 디바이스 장치 드라이버(Driver)가 4GB 이상 메모리 환경을 고려하지 않고 만들어졌기 때문에 발생한 문제였습니다.
5. 이런 장치 드라이버 호환성 문제를 피하기 위해 윈도우 클라이언트(XP, Vista, 7)에서는 4GB까지만 메모리 관리(Memory Management)를 할 수 있도록 한 것 입니다.
Q2) 4GB메모리가 전부 보이지(인식)되지 않고 3(.xx)GB 정도로 보여요, 왜 그런가요?
아래 그림은 제 Windows 7에서 시스템 정보(msinfo32.exe)를 실행시켜 얻을 결과입니다, 실제 설치된 메모리는 4GB지만 윈도우가 이용할 수 있는 실제 메모리는 3GB로 인식하고 있습니다.
하나 더 아래 그림은 작업 관리자에서 나타난 값입니다, 마찬가지로 실제 메모리를 3GB 정도만 인식하고 있는 것을 볼 수 있습니다.
결론부터 말씀 드리면 이 현상의 원인은 컴퓨터의 칩셋(Chipset)과 연결된 장치(비디오 카드, Lan 카드 같은)가 가지고 있는 메모리 때문에 실제 장착된 메모리보다 적게 나타나는 것입니다. 윈도우는 '실제 메모리'에 나타난 '전체' 크기 만큼의 메모리만 사용할 수 있므며(즉 위와 같은 경우에는 전체 4GB를 사용하지 못합니다) 이는 하드웨어 이슈 입니다. 이와 연관있는 디바이스 요소로는 System BIOS, Motherboard Resources (I/OxAPIC), Memory Mapped I/O, PCI Express Configuration Space, Additional PCI Device Memory (Graphics Aperture), VGA Memory 등이 있습니다.
어려운 이야기가 될 수 있으니 쉬운 이해를 위해 먼저 아래 그림을 보시죠. 시스템이 시작할 때 Physical Address Map(이하 PAM)이라는 걸 만듭니다, PAM은 RAM과 각 장치들이 가지고 있는 메모리의 주소 정보로 일종의 '순서' 혹은 '차례'를 만들어 Windows에게 넘겨줍니다, 그러면 Windows는 PAM 범위의 메모리만 사용(Access) 할 수 있습니다.
그런데 PAM이 만들어 질때 메모리(RAM)만 가지고 만드는 것이 아니고 모든 종류의 장치가 가진 디바이스 메모리(비디오 카드, Lan 카드가 가지고 잇는 메모리를 칭함)까지 포함합니다, 처음에는 RAM만 가지고 PAM을 만들어 가다는 중간에 디바이스 메모리가 끼어들게 됩니다, 그러면 PAM 중간에 디바이스 메모리가 포함되고 다시 PAM에 추가되다만 나머지 RAM이 PAM에 추가 되는데 이때 추가된 RAM이 4GB 범위 밖에서 만들어집니다. x86 Standard Memory management Mode를 사용하는 32-bit Windows는 4GB 메모리 영역까지만 사용(Access) 할 수 있는데 디바이스 메모리 때문에 RAM이 4GB 범위 밖으로 밀려나 해당 범위의 메모리가 보이지 않게 되는 것입니다.
위 그림은 총 4GB메모리 환경에서 디바이스 메모리가 총 500MB이기 때문에 사용할 수 있는 총 메모리가 3.5GB로 줄어든 예입니다. 밀려난 500MB는 윈도우가 Access 할 수 없는 영역이기 때문에 사용할 수 없습니다. 이 이슈는 하드웨어에서 해결해야 할 이슈입니다. (이전에 사용한 '문제'라는 표현은 오해를 가져 올수 있어 '이슈'로 변경하였습니다, 여기서 하드웨어란 칩셋을 의미합니다 )
*참고로 32비트 Windows 서버 관련한 4GB 제한에 대한 이야기는 이전에 ‘누가 내 메모리를 훔쳤나?’라는 글로 포스팅한 적이 있습니다, 서버에 관심 있으신 분들은 참고로 읽어 보시기 바랍니다.
Q3) 정말 디바이스 장치들이 메모리 중간에 끼어 들어 메모리가 밀려났는지를 어떻게 해야 볼 수 있죠?
이전에 어떻게 해야 볼 수 있을까 고민 많이 했는데(디버거 봐야 하나.. 등등 ^^;) 의외로 장치 관리자(devmgmt.msc)에서 간단하게 보실 수 있었습니다. 아래 내용은 32비트 클라이언트뿐만 아니라 64비트와의 비교를 보여드리기 위해 제 테스트 머신에 듀얼 부팅으로 Windows Vista 32비트와 64비트를 설치해 테스트를 진행하였습니다.
32 비트 Windows 클라이언트
아래 그림은 32비트 Vista 작업 관리자(taskmgr.exe)에서 보이는 Physical Memory의 모습입니다, 4GB를 장착했지만 전체가 3.3GB정도가 나옵니다.
그렇다면 ‘작업 관리자’가 말하는 Windows가 실제 인식한 Physical Memory 범위는 어떤 모습일까요? 아래 그림은 Meminfo.exe를 이용하여 Windows가 실제 인식하는 Physical Memory 범위를 출력한 결과입니다. (meminfo는 전에 소개해 드렸던 Windows Internals 5’th Edition을 쓴 Alex Ionescu가 만들었습니다)
메모리를 표기할 때 16진수로 표현하고 이를 00000000~FFFFFFFF로(0MB에서 4GB)로 표현합니다. 위 결과를 보시면 Physical Memory 범위가 ‘00001000~0009F000’과 ‘00100000~CFDFF000’ 두 범위로 나눠져 있으며 대략 3.4GB 정도의 크기 입니다.
그럼 두 범위에 중??에 빠진 ‘0009F000~00100000’과’CFDFF000~FFFFFFFF’ 사이 영역은 왜 Windows에서 인식하지 못한 것 일까요? 앞에서 말씀 드렸듯이 디바이스가 해당 영역을 점유해 윈도우가 사용(Access)할 수 있는 메모리가 아니기 때문입니다.
디바이스가 점유한 모습은 ‘장치 관리자(devmgmt.msc)’를 통해 확인 하실 수 있습니다, ‘장치 관리자(devmgmt.msn) > 보기 > 리소스(연결별) > 메모리’를 선택합니다, 그러면 아래 그림과 같이 비디오 카드 Radeon X13000이 ‘D0000000~DFFFFFFF’(대략 268MB)과 ‘FE900000~FEAFFFFF’(대략 2MB) 영역, 즉 Physical Memory 범위에서 제외되었던 곳에 자리 잡고 있음을 확인 할 수 있습니다.
32비트에서는 4GB에서 밀려난 메모리를 볼 수 없습니다, 그럼 밀려난 나머지를 보기 위해 우리 64비트를 살펴보도록 하죠~
64비트 Windows 클라이언트
아래는 64비트 Vista 작업 관리자(taskmgr.exe)에서 보이는 Physical Memory의 모습입니다, 4GB 모두 보입니다.
Meminfo로 본 Physical Memory 범위입니다, 64비트라 Address 범위부터가 다르죠? Memory Address가 4GB를 넘고 메모리 또한 4GB 범위 모두 나타납니다.
장치 관리자에서 본 모습입니다.
32비트에서 본 것과 마찬가지로 위 빨간 박스의 부분은 268MB정도 되고 아래가 2MB정도가 됩니다. 중간에 비디오 카드가 끼어 들었지만 4GB 이후 주소인 '0000000100000000~000000012C000000(실제 메모리 5GB 쯤의 자리)'에서 나머지 720896KB(대략 720MB)를 인식한 것을 볼 수 있습니다. 즉 디바이스가 메모리를 4GB 영역 밖으로 밀어냈다고 해도 128GB까지 인식하는 64bit Addressing 때문에 문제없이 모든 Physical Memory가 보입니다.
처음에 드렸던 예로 이런 상황에서 64비트를 그림으로 표현 하면 아래와 같습니다.
Q4) 그럼 32비트 클라이언트가 4GB 이상을 사용(Access, Addressing)하려면 어떻게 해야 할까요?
정답은 32비트 클라이언트는 4GB 이상을 사용할 수 있는 방법이 없습니다, 4GB 이상 메모리의 사용이 필요하다면 64-bit Windows 클라이언트를 사용하십시오.
현재는 32-bit 환경에서 64-bit 환경으로 넘어가기 위해서는 우선 64비트로의 인식전환이 필요할 것입니다. 다음으로 64비트 전용 응용프로그램들이 많이 나와야 할 것 입니다, 32비트 응용프로그램을 에뮬레이션 하기 위한 WOW 64 Subsystem이 있기는 하지만 모든 응용프로그램에 호환성을 보장하지 않고 32비트 응용프로그램 구조상 64비트 Windows에서 실핼 할 때 64비트가 제공하는 무한(?)한 메모리를 이용할 수 없는 제한이 있습니다.
*64비트 윈도우와 응용프로그램에 대한 이야기는 예전에 포스팅 한 글이 있습니다, 읽어 보시고 추가적인 이해에 도움이 되셨으면 합니다.
Windows 64bit Computing에 대한 오해 혹은 잘못된 상식
https://blogs.technet.com/sankim/archive/2007/12/28/windows-64bit-computing.aspx
Q5) Windows XP를 보면 PAE를 지원하는데 이는 XP도 PAE를 사용하면 4GB 이상을 사용할 수 있다는 의미 아닌가요?
Windows XP SP2 부터 나온 DEP(Data Execution Prevention)를 사용하기 위해서는 기본적으로 PAE가 활성화(Enable)되어 있어야 합니다, 그래서 PAE 기능을 활성화 할 수 있도록 한 것입니다. 이는 Windows Kernel에서 32bit에서는 존재하지 않는 64bit PTE table의 field를 이용하기 때문입니다.
To use these processor features, the processor must be running in Physical Address Extension (PAE) mode. However, Windows will automatically enable PAE mode to support DEP. *해당 문서를 보시려면 여기를 클릭하세요.
참고로 PAE를 활성화 하는 경우와 반대의 경우 윈도우가 시작 시 로드하는 커널 파일은 아래와 같습니다.
CPU 수에 따른 환경 |
기본 |
PAE 활성 |
Uniprocess(단일 CPU) |
Ntoskrnl.exe |
Ntkrnlpa.exe |
Multiprocess(다중 or 코어 CPU) |
Ntkrnlmp.exe |
Ntkrpamp.exe |
Q6) 번 외 질문인데요, 도구마다 메모리 측정 결과가 각기 조금씩 다른 경우가 있어요 왜 그렇죠?
위 그림에서 작업관리자는 3.3인데 왜 meminfo는 3.4냐고 반문하실 수도 있습니다 또한 제가 종종 받는 질문 중 하나가 작업 관리자에서 ‘사용가능’ 항목과 성능 모니터에서 ‘Available %메모리%’의 값이 다르다는 것입니다. 이는 각 도구마다 메모리를 계산하기 위한 항목 수집 기준이 조금씩 달라서입니다, 크게 차이가 나는 것이 아니므로 이번 포스팅에서는 무시하셔도 좋습니다. 언제 작업 관리자에 나온 항목에 대한 자세한 설명을 드리겠습니다. (약속만 드리고 지키지 못하는 것들이 많지만 이번 약속은 꼭!!)
그럼 여러분 좋은 하루 되세요~
* 이전에 댓글에 추가로 명시 했습니다만 '장치 메모리', 혹은 'MMIO'라고만 명시 한것에 대해서 모호하다는 의견이 있어 본문 내용과 하단 부분에 함께 추가 합니다. ^^ 4GB 전체 사용하지 못하는 이슈에 영향을 끼치는 디바이스 요인으로 System BIOS, Motherboard Resources (I/OxAPIC), Memory Mapped I/O, PCI Express Configuration Space, Additional PCI Device Memory (Graphics Aperture), VGA Memory *등(헥헥헥..)이 있습니다. 그러나 말씀안드려도 이들 모두 '장치 메모리'의 범주 임을 알 수 있는 센스~!
[참고자료]
Pushing the Limits of Windows: Physical Memory, Written by Mark Russinovich *이번 포스팅의 대부분의 아이디어가 이 글에서 나왔습니다, 꼭 한번 읽어 보시기 바랍니다.
Windows Internals, Chapter 7 Memory Management
Intel 64 and IA-32 Architectures Software Developer’s Manual, Intel 64 and IA-32 Architectures
여기에는 M$의 문제가 맞지만 원인제공은 인텔이 했습니다.
8비트부터 64비트까지 하위 호환성을 위해 인텔은 세그먼테이션 이라는 다소 특이한 어드레싱 기법을 고안했는데 32비트부터는 보호모드라는 작동방식을 써야했고 이것이 문제되는 것입니다.
반면에 Paging 어드레싱만 사용하는 ARM같은 RISC프로세서에는 그런문제가 없습니다.
세그먼테이션은 세그먼트 주소와 인덱싱 주소를 오버랩시겨 어드레싱하는 방식이며 (CS,DS,.SS.ES 레지스터 사용),
페이징은 오버랩 없이 디스크섹터 접근과 유사한 개념의 어드레싱 체계입니다.. (1 페이지 크기는 역시 4KB)