해당 글은 100 퍼센트 정확하지 않을 수 있으며 제가 경험에서 취득한 것들을 정리하는 형태의 글입니다. 그래서 혹시 잘못된 부분을 발견하여 코멘트 주신다면 감사합니다.

해당 시리즈가 업데이트 된다면 업데이트 내용 또한 기록될 것 같습니다.


컴퓨터의 구조는 무척이나 다루기 어려운 부분이다. 정확하게 이렇다라고 말하기 어려운 부분들도 있고, 시대에 따라 달라진 부분들도 많기 때문이다. 그래도 최대한 아는데까지 정리해보려고 한다.

일단 메모리는 CPU가 작업할 내용들을 저장하는 공간이다. 보통 휘발성이라 전원을 끄면 내용이 날아간다. 주기억장치라고 하며 보통 책상에 비유된다. 보통 여기까지가 컴퓨터 기초 구조에서 배운다. 하지만 램은 전원을 끈다고 바로 데이터가 날라가는 것이 아니고 서서히 커패시터에서 사라지는 것이기 때문에 액체 질소등으로 얼리면 최대 일주일까지도 보관할 수 있다.

일단 운영체제는 램에 상주한다. 당연하다. 램에 상주하지 않으면, 갑자기 운영체제가 꺼질 수도 있다. 그렇기에 커널과 운영체제를 위한 프로그램 말고는 포인터 등을 사용해도 실제 램을 사용하는 경우는 거의 없다. 주로 가상 메모리를 사용한다.

프로그램은 가상 메모리 주소를 참조하고, 거기서 실제로 필요한 양은 램에 할당하고, 더 필요하면 디스크 용량 중에 일부를 램으로 쓰는 스왑에 할당하는 것이 기본적인 프로세스라고 할 수 있다.

이런 가상 기억장치를 구현하는 일반적인 방법에는 페이징(paging)과 세그먼테이션(segmentation) 기법이 있다. 페이징 기법은 가상메모리와 메모리를 같은 크기로 할당하는 것이고, 세그먼테이션 기법은 가상메모리와 메모리를 다른 크기로 할당하는 것이다.

그래서 페이징은 프로그램 프로세스가 페이지 단위보다 많거나 적게 요구하게 되면 마지막 페이지 프레임은 전부 사용하지 않고 남는 문제가 발생하고(내부 단편화), 세그먼테이션은 하드디스크가 조각나는 것처럼 쓰지 않는 공간들이 많은 수의 작은 공간들로 나누어져 못 쓰게 될 수도 있다(외부 파편화).

페이징과 세그먼테이션은 아키텍처를 따라간다. 보통 우리가 흔히 이야기하는 아키텍처인 x86-64는 페이징 기법을 사용한다. 세그먼테이션 기법을 사용하는 아키텍처로는 아폴로나 IBM i 시리즈 처럼 상대적으로 구형 아키텍처들에게 사용된다. 이는 아마도 현대에 올수록 메모리 가격이 용량 대비 저렴해졌기 때문에 굳이 세그먼테이션까지 하며 메모리 제어를 할 필요가 없었기 때문이며, 고용량 메모리일 수록 외부 파편회 문제가 심각해질 수 있기 때문이다.

x86-64 란 무엇일까? 초기부터 개인컴퓨터를 사용했던 사람들은 386이니 486이니 했던 것을 기억할 것이다 그것은 정확히 80386, 80486 컴퓨터를 의미한다. 80386 컴퓨터는 인텔에서 새롭게 32비트 CPU 명령셋을 만든 것이며 이것이 x86이 시초이다. 그리고 인텔은 이후에 또다시 새롭게 64비트 CPU 명령셋을 사용하는 CPU를 출시하였고 이는 x64라고 부른다. 또다시 그것에 맞춰 소프트웨어등을 개발해야하는 소프트웨어 회사 입장에서는 x86 명령어 셋과 호환되면서 64비트를 지원하는 AMD64,우리가 흔히 이야기하는 x86-64 아키텍처를 선호하게 되면서 현대 CPU 아키텍처는 x86-64를 사용한다.

이것에 대한 보충 설명으로 x86 아키텍처까지는 세그먼테이션을 사용했으며, 현대 CPU가 32비트, 64비트 운영체제를 모두 지원하는 것도 이와 같은 이유에서이다. 또한 32비트 운영체제는 메모리 주소를 32비트로 사용하여 램을 4기가까지만 인식하고, 64비트 운영체제는 메모리 주소를 64비트로 사용하여 램을 4기가 이상도 인식하는 것이다.

“가상 메모리(페이징) – 페이지 테이블(가상메모리주소를 물리메모리에 맵핑) – 물리메모리(프레임) – 스왑”

이렇게 정리할 수 있다. 실제로 이것을 다루는 것은 운영체제이기에 운영체제 특성에 따라 컨트롤 특성은 다를 수 있다. 일례로 ARM 베이스의 M1 아키텍처 기반의 맥이 처음 탑재하고 출시한 맥 OS Big Sur 같은 경우 SWAP 메모리를 무제한 가까이 땡겨다 쓰는 경우도 있었다.(기본 메모리의 2배 가까이를 스왑으로 땡겨 씀) 그럼에도 불구하고 그렇게 크게 느려졌다는 생각은 할 수 없었는데 램과 SSD까지 모두 일체형인 SOC여서 그런게 아니었을까란 생각을 했다. 이렇게 쓰면 분명 SSD 수명이 길진 않을텐데, 어차피 애플은 정책적으로 구형 기기들을 밀어내어 지속적으로 새 제품 구매를 유도하기 때문에 가능한 정책이란 생각도 들었다.

대충 기술적인 내용은 이렇고 실제로 램의 사용량의 보는 것에 대해 알아보고자 한다. 다다익램이라고 해서 램은 많을 수록 좋다는 말이 있지만 결국 램은 모자르면 디스크 스왑을 사용하고 이것은 너무 느리기 때문에 모자르지만 않으면 된다.

유닉스 계열에서는 free 를 소개하고자 한다. htop나 top나 btop나 sar 처럼 종합적으로 표시해주는 툴은 많지만 기본적인 개념은 같으므로 free 를 일단은 소개해보기로 한다.

free의 경우 보통은 free -m 으로 명령어를 날리는 편이다. 왜냐하면 그냥 free를 하면 킬로바이트 단위로 숫자가 나오는데 이것을 계산하는 것은 꽤나 귀찮기 때문에 -m 옵션으로 적절히 보기 편한 숫자로 끊어주는 것이다.

free -m 명령어를 치면 보통 이렇게 나온다.

구형 리눅스 커널

             total       used       free     shared    buffers     cached
Mem:          8105       8025         80          0        214       6570
-/+ buffers/cache:       1239       6865
Swap:         4094          0       4094

현재 리눅스 커널


               total        used        free      shared  buff/cache   available
Mem:             679         494         212          10         191         184
Swap:              0           0           0

구형 커널은 buffers/cache 행에 있는 free가 swap 없이 할당 가능한 양이고, available 열에 있는 데이터가 swap 없이 할당가능한 양이다.

여기 있는 cache는 프로세스 파일들의 내용을 buffer의 경우는 메타데이터들을 저장한다. 만일 이것들을 다 반환했음에도 물리 메모리량이 모자르다면 Swap에 할당하게 되는 것이다.

윈도우즈에는 보통 작업관리자를 통해 메모리의 양을 확인하게 될 것이다.

Image

사용 중인 메모리는 실제로 사용 중인 물리 메모리량을 나타낸다.

압축이라고 되어 있는 것은 사용하지 않는 메모리들을 압축한 양을 나타내며, 그 옆에 사용 가능은 실제로 사용 가능한 물리 메모리량을 나타낸다.

커밋됌은 메모리와 스왑의 합(윈도우즈는 페이지 파일이라고 부른다)으로 현재 4 기가 정도 스왑을 잡고 있는 것으로 추측할 수 있다. 스왑을 얼마나 잡을지는 윈도우즈에서는 기본 설정에서 자동으로 되어 있다.

캐시됨은 리눅스와 마찬가지로 프로세스의 내용을들을 캐시하는 것인데 보통 자동적으로 반환이 되나 RamMap이란 프로그램을 통해 수동으로 캐시를 정리할 수도 있다.

페이징풀과 비페이징풀은 커널과 관련된 부분이다.

비페이징풀은 가상 메모리를 사용하지 않고 실제 메모리를 사용하는 풀로 주로 OS나 드라이버등이 로드된다. 반면 페이징풀은 데이터를 디스크로 이동하여 기록할 수 있는 객체들로 주로 레지스트리 데이터구조와 레지스트리 키 등이 로드된다.