메모리 페이징 관련 질문 입니다.

swunk의 이미지

책을 보고 있는데 명확하게 이해가 안되서 두어가지 질문 드립니다.

x86/32 bit 환경에서의 이야기 입니다.

page directory는 1024개의 엔트리를 가지고 있습니다. (linear 주소의 상위 10비트를 사용하여 매핑하기 때문에)

(1) page directory는 프로세스 마다 고유한 것으로 프로세스마다 하나씩 가지고 있고 1024개의 page directory 각각의 엔트리는 하나의 page table을 가르키고 있습니다. 그렇다면은 page table은 1024개가 존재한다는 야기가 되는데 그러한 page table 들은 메모리에 상주해 있는 건가요 ? 상주해 있다면 페이지 테이블을 저장하는 메모리만 상당할것 같은데요...얼추 계산해 보면 하나의 페이지테이블 엔트리 사이즈가 4byte 이니깐 4*1024*1024 byte 만큼 잡아먹고 있다는 이야기인데 리눅스에서 그렇게 멍청하게 처리하지는 않을꺼 같구요..제가 어디를 잘못 알고 있는건가요 ?

(2) 위와 같은 이야기를 할때 항상 32 bit의 linear address를 가지고 상위 10 비트는 뭐고 중간 10-비트는 뭐고 이야기를 하는데...그 linear address라는게 어디서 나오는 건가요 ? 프로그래머가 응용프로그램에서 바라보는 pointer값을 의미하는 건가요?

(3) 질문을 하면서 생각해보니 프로세스 하나에서 즉, 해당 프로세스의 page directory의 1024개의 엘리먼트 중 어느것이 선택될 수 있고 그 엘리먼트는 1024개의 page table중 어느것을 선택할 수 있으니 모두 메모리에 상주해 있어야 겠다는 생각이 들기도 하는데...

(4) 얼마전에 winCE 6.0이 출시된 기사를 본 적이 있습니다. 이전 버전에 비해서 특징이 나왔는데 32000개의 프로세스를 동시에 생성할 수 있고, 각각의 프로세스에 2기가의 메모리를 할당할 수 있다고 나온거를 봤습니다. 이게 어떤 의미를 갖는 건가요? 리눅스 같은 경우는 동시에 생성할 수 있는 프로세스의 갯수는 모르겠지만 프로세스당 4기가의 메모리를 할당 하잖아요 ?

(5) 위의 질문 관련해서 친구랑 얘기를 하다가 윈도우 XP에서는 "마야" 같이 메모리를 엄청 잡아먹는 프로그램같은 경우에는 4기가 이상의 메모리를 할당한다는 얘기를 들었습니다. 그래서 저는 그건 말도 안된다. 리눅스 같은 경우도 extende paging을 지원하기 전에는 4기가 이상의 메모리를 프로세스에게 할당하는 것은 불가능 한것으로 알고 있고 윈도우도 별반 다르지 않다라고 얘기를 했더니 이 친구놈이 윈도우 작업관리자에서 프로세스 창을 띄어 놓고 보면 5기가 넘게 메모리를 사용하는 놈을 봤다고 계속 우기더 군요? 이게 가능한 얘긴가요? 그리고 윈도우 작업관리자에서 나오는 메모리 사용량은 정확하게 무엇을 나타내는지 아시는 분 계시나요?(실제 물리 메모리에 올라와 있는 놈의 크기인지 아니면 swap out된 놈 까지 포함하는 건지 궁금합니다.)

질문을 하다보니 너무 길어 졌네요...
고수님들의 답변 부탁드립니다.

kslee80의 이미지

4) WinCE 5.0 이하를 접하신 경험이 없으셔서 그렇게 받아들이시는것 같습니다.
WinCE 5.0 이하 OS 들의 동시 프로세스 갯수는 32개, 프로세스당 32MB 의 메모리가 할당됩니다. -_-;;;
(메모리 할당 크기에 대해서 이견이 있으신 분들이 있으실 수도 있으니 조금 더 명확하게 하자면,
프로세스들이 공유하는 공간인 1G~2G 영역에 할당받는 경우를 제외한 수치입니다....)
32MB 의 '물리메모리' 도 아닙니다. 32MB 의 '가상메모리' 입니다 -_-;;;

리눅스는 2.2 버젼이였던가 2.4 버젼이였던가에서 프로세스 갯수 제한을 없앴습니다. 따라서 그 이후버젼 커널에서는
프로세스 갯수 제한은 없습니다. (메모리가 부족해서 프로세스를 못 만드는 경우는 있겠죠..당연히..)

5) PAE 를 의미하시는것 같은데....PAE 는 꽤나 예전부터 프로세서들이 지원했습니다.
정확한 시기는 모르겠는데, 인텔의 Pentium 계열 CPU 들은 다 지원하는걸로 알고 있습니다.
(AMD 는 정확하게 모르겠습니다. K7(Athlon) 이후 CPU 들은 지원할 것 같은데....)

swunk의 이미지

4번 질문에 답변하신 것 처럼 리눅스는 프로세스 생성의 제한도 없고, 프로세스당 할당하는 가상메모리도 4기가 이고...그렇다면 winCE 6.0에서 특징으로 내세우는 것들이 리눅스에서는 오래전에 이미 해놓은 것들이잖아요? 별로 대단하지 않은것 같은데 아주 대단한것 처럼 말하길래 제가 아는것과 먼가 다른것이 있는것 같아 질문을 드린겁니다.

5번 답변 관련해서...리눅스에서는 제가 알기로 PAE를 적용하려면 커널컴파일시에 옵션을 따로 지정해 줘야하는것으로 알고 있습니다.
이런 기능이 윈도우에 구현되어 있나요 ?

kslee80의 이미지

4) WinCE 가 사용되는 분야를 생각해 보시면 됩니다.
그쪽 분야에서는 솔직히 프로세스 생성 제한 확대 및 프로세스당 가상메모리 한계 확대는 굳이 크게 와닿지는 않지만,
시장의 요구에 의해서 개선된 사항이라고 생각됩니다.
그리고 사실, WinCE 5.0 과 비교하면 매우 대단하게 개선된 것이기에 광고를 멋지게 하는 것일수도 있죠 -_-;;;
어짜피 그쪽 시장에 대해서 MS 에서는 Linux 는 안중에도 없을 겁니다....

5) '이런 기능' 이 PAE 적용을 말씀하시는 것인지,
'PAE 를 활성화 하는 기능' 을 말씀하시는 것인지 명확하게 모르겠습니다만, (제가 난독증이 있을지도...==;;; )
인텔과 MS 의 유착관계( ? ) 를 생각해보면, ('윈텔' 이라는 단어가 존재하는 이유죠;; )
PAE 가 이미 윈도우즈군에는 적용되어 있을 것이라고 생각합니다.
커널을 건드릴 수 없는 윈도우즈에서는 'PAE 를 활성화 하는 기능' 은 없겠죠. 활성/비활성이 딱 정해져서 출시되고,
비활성 상태로 출시된 경우라면, 차후 패치를 통해서 활성화 한다거나 하는 수준이겠죠.

headbang의 이미지

(1) 프로세스마다 실제 할당된 메모리에 해당하는 Page Table만 가지고 있습니다.
나머지 Page Directory 엔트리들은 None으로 설정되어있습니다.
예를 들자면 "hello world\n" 만 출력하고 끝나는 프로세스의 경우 상식적으로 코드 영역, 힙 영역, 데이터 영역, 스택 영역 등등이 모두 4MB 이하이므로 4개 정도의 Page Table만 할당받겠죠.

(2) 프로그램이 발생하는 모든 주소는 linear address입니다. 실제 메모리로의 접근은 MMU 하드웨어가 linear address를 physical address로 변환하여 접근하게 됩니다.

(3) 앞서 말씀드린대로 할당되지 않은 메모리에 해당하는 Page Directory 엔트리는 None으로 설정되어있습니다.
프로세스가 사용자 주소 영역을 접근하여 MMU가 None으로 설정되어 있는 Page Directory를 접근하면 Page Fault가 발생하며 그 처리는 두가지 경우로 나눌 수 있있습니다.
- 정당한 접근: vmarea_struct를 조사하여 정당한 접근이면 Page Table을 할당하여 Page Directory에 등록하고, 다시 Page Frame을 할당하여 Page Table에 등록합니다.
- 정당하지 못한 접근: vmarea_struct를 조사하여 잘못된 메모리 접근이면 잘못된 메모리 접근을 나타내는 signal을 보내게 됩니다.

- 기타: 한 프로세스에 할당될 수 있는 최대 메모리 양은 PAE가 설정여부와 전혀 무관합니다.
엄밀히 말하면 linear address space와 physical address space 중 작은 놈에 의해 결정되겠죠. PAE가 설정되어 physical address space가 2^36 B (64 GB)가 되더라도 linear address space 가 2^32 B (4GB) 이고 더구나 사용자 주소영역이 3GB 이라면 최대로 할당할 수 있는 메모리는 3GB가 됩니다.

swunk의 이미지

예를 들어서 어떤 응용프로그램이 0x2000 0000 부터 0x3003 ffff까지 가상 메모리를 할당 받았다고 한다면
page directory 엔트리중 128 ~ 192 까지는 해당 페이지 테이블을 가르키고 나머지 960개는 "0"로 설정되어 있고..
각각의 페이지테이블들은 모두 0 ~ 63 번째 엔트리 까지만 설정되어 있고 나머지 들은 모두 "0"으로 설정되어 있겠네요...
그리고 모든 경우에 마지막 12비트 즉, offset값들은 항상 fff로 설정되어 있어야 하고...
저는 지금까지 페이지테이블은 시스템에 하나가 존재하는 줄 알았는데 위에 내용이 맞다면 프로세스 마다 하나씩 존재하게 되겠네요...
제가 맞게 이해 했나요 ?

headbang의 이미지

네, 프로세스마다 서로 다른 Page Table를 가지고 있습니다.

엄밀히 말하자면 주소 0GB ~ 3GB 인 User Address Space에 해당하는 Page Table은 프로세스 마다 서로 다른 Page Table을 가지고 있으며
반면 주소 3GB ~ 4GB 인 Kernel Address Space에 해당하는 Page Table은 모든 프로세스가 공유합니다.

또다른 예외로 동일한 thread 그룹에 속하는 쓰레드(혹은 light weight process)끼리는 속성상 Address Space를 공유해야 하므로 이런 경우 굳이 Page Directory와 Page Table를 따로 할당 받지않고 공유합니다. (이런 프로세스는 fork()가 아닌 clone()으로 생성됩니다.)

(1) 첫번째 질문의 답변

Linux의 paging 방식은 demand paging입니다. 즉, malloc() 등을 통해 가상주소영역을 아무리 많이 할당받더라도 해당 가상 주소를 접근하지 않으면 물리 메모리(page frame)을 할당하지 않으며 해당 Page Table도 할당 받지 않습니다. 참고로 malloc()은 힙 영역에 해당하는 vmarea_struct의 가상주소영역을 늘리는 일을 합니다.

이런 이유로 질문에서처럼 가상 메모리를 할당받았다는 사실만으로 Page Table할당과 설정에 영향을 미치지 않습니다. 가상 메모리를 할당 받은 후 실제 접근을 해서 해당 물리 메모리가 할당되었다고 가정을 하면,

- User Address Space에 해당하는 Page Directory 엔트리는 0 ~ 767 까지인데 그 중 128 ~ 192 는 해당 Page Table를 가르키는 게 맞습니다. 나머지 0 ~ 127, 192 ~ 767 은 비어 있습니다.
- Kernel Address Space에 해당하는 Page Directory 엔트리는 768 ~ 1023 인데 이들도 나름대로 설정되어 있겠죠.

(2) 두번째 질문의 답변

질문에서 각각의 Page Table들은 0 ~ 63 번째 엔트리까지만 설정되어있는지 물어보셨는데, 제가 생각에는 다음과 같이 설정되어 있을 것 같네요.
- Page Table 128 ~ '191'의 경우에 모든 엔트리는 해당 page frame을 가르킴,
- 마지막 Page Table 192 경우에만 0 ~ 63 번째 엔트리는 해당 page frame을 64 ~ 1023 엔트리는 비어있음

(3) 세번째 질문의 답변

"모든 경우에 마지막 12비트 즉, offset값들은 항상 fff로 설정되어 있어야 하고..." --> 그렇지 않습니다.
Page Directory와 Page Table 엔트리의 마지막 12 비트는 주소값의 일부가 아니라 그 엔트리가 사용중인지 여부, Read/Write 권한, 해당 page가 메모리에 있는지 등등의 정보를 가지고 있습니다.
Page Table, Page Directory의 엔트리들이 가르키는 page frame의 물리주소는 4KB로 정렬 (align) 되어 있기 때문에 물리 주소의 마지막 12 비트는 항상 '0'입니다. 따라서 그 12 비트씩 저장공간을 주소값이 아닌 다른 용도로 사용할 수 있습니다.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.