6-1
1. RAM의 기본 특성
• 휘발성 저장장치: RAM(Random Access Memory)은 전원이 꺼지면 저장된 내용이 모두 사라지는 휘발성(volatile) 저장장치입니다.
• 보조기억장치와의 차이: 하드디스크(HDD), SSD, USB와 같은 보조기억장치는 전원이 꺼져도 내용이 유지되는 비휘발성(non-volatile) 장치입니다,.
• 역할: CPU는 실행할 프로그램의 명령어와 데이터를 RAM에서 가져와 실행하며, RAM은 실행할 대상을 저장하고 보조기억장치는 보관할 대상을 저장하는 역할을 합니다,.
2. RAM의 용량과 성능의 관계
램의 용량은 컴퓨터의 성능, 특히 다중 작업(멀티태스킹) 능력에 중요한 영향을 미칩니다,. 이를 이해하기 위해 **'책상(RAM)'과 '책장(보조기억장치)'**의 비유를 사용합니다.
• 용량이 작을 경우: 책상이 작으면 필요한 책을 읽을 때마다 책장에 왔다 갔다 해야 하므로 시간이 오래 걸리고 여러 작업을 동시에 하기 어렵습니다.
• 용량이 클 경우: 책상이 크면 많은 책을 미리 올려두고 바로 읽을 수 있어, 보조기억장치에 접근하는 횟수가 줄어들고 동시에 여러 프로그램을 빠르게 실행하는 데 유리합니다,.
3. RAM의 종류
램은 크게 네 가지 종류(DRAM, SRAM, SDRAM, DDR SDRAM)로 나뉩니다.
DRAM (Dynamic RAM)
• 특징: 데이터가 동적으로 사라지는 특성이 있어, 전원이 공급되어도 시간이 지나면 데이터가 소멸됩니다.
• 재활성화(Refresh): 데이터 소멸을 막기 위해 **주기적으로 데이터를 다시 저장(리프레시)**해야 합니다.
• 장점: 소비 전력이 낮고, 가격이 저렴하며, 집적도가 높아 대용량으로 설계하기에 유리합니다. 이러한 이유로 우리가 흔히 말하는 **메인 메모리(주기억장치)**로 주로 사용됩니다.
SRAM (Static RAM)
• 특징: 전원이 공급되는 동안 데이터가 사라지지 않는 정적인 램입니다. (단, 휘발성이므로 전원을 끄면 사라집니다).
• 장점: DRAM보다 입출력 속도가 훨씬 빠릅니다.
• 단점: 소비 전력이 높고 가격이 비싸며, 집적도가 낮아 대용량 제작이 어렵습니다.
• 용도: 대용량이 필요 없지만 빠른 속도가 중요한 캐시 메모리에 주로 사용됩니다,.
SDRAM (Synchronous DRAM)
• 특징: 클럭 신호에 맞춰 동작하는(동기화된) 발전된 형태의 DRAM입니다.
• 동작: 클럭 신호가 발생할 때마다 박자를 맞춰 데이터를 주고받을 수 있습니다.
DDR SDRAM (Double Data Rate SDRAM)
• 특징: 대역폭(데이터를 주고받는 길의 너비)을 넓혀 데이터 전송 속도를 비약적으로 높인 SDRAM입니다,. 현재 가장 대중적으로 사용되는 램의 종류입니다,.
• 세대별 발전 (대역폭 차이):
◦ SDR SDRAM: 한 번에 하나씩 데이터를 주고받는 1차선 도로와 같습니다.
◦ DDR SDRAM: SDR보다 대역폭이 2배 넓은 2차선 도로와 같습니다.
◦ DDR2 SDRAM: DDR보다 2배, SDR보다는 4배 넓은 대역폭을 가집니다.
◦ DDR3 SDRAM: SDR보다 8배 넓은 대역폭을 가집니다,.
◦ DDR4 SDRAM: SDR보다 16배 넓은 대역폭을 가지며, 현재 가장 흔히 사용되는 방식입니다.
요약하자면, **메인 메모리로는 대용량화가 쉬운 DRAM(그중에서도 DDR4 SDRAM)**이 쓰이고, 캐시 메모리로는 속도가 빠른 SRAM이 사용됩니다,,.
- D드라이브 (HDD/SSD): 책꽂이입니다. 책(데이터)을 꽂아두면 전원을 꺼도 그대로 남아있죠.
- DRAM (메모리/RAM): 책상입니다. 공부하려고 책(데이터)을 펼쳐놓는 곳이에요. 전원을 끄면 다 날아갑니다.
2. 왜 이름이 "Dynamic(동적)"인가요?
DRAM의 구조 때문입니다. DRAM은 아주 작은 **'전기 그릇(커패시터)'**에 전기를 채워서 데이터를 저장합니다.
- 전기가 차 있으면 = 1
- 전기가 비어 있으면 = 0
그런데 문제가 하나 있어요. 이 그릇이 미세하게 구멍 난 종이컵 같아요. 전기를 채워놔도 시간이 지나면 전기가 야금야금 다 새어나가 버립니다.
- 그냥 가만히 놔두면? → 전기가 다 새서 데이터(1)가 0으로 바뀌고 사라짐!
- 그래서 어떻게 하나요? → 전기가 다 새기 전에 "어이쿠, 거의 다 비었네!" 하고 다시 꽉 채워줘야 합니다.
이걸 **리프레시(Refresh)**라고 하고, 가만히 있지 못하고 계속 전기를 다시 채워줘야(움직여야) 유지되기 때문에 **'동적(Dynamic)'**이라는 이름이 붙은 겁니다.
3. "전원이 공급되어도 사라진다"는 말이 그 소리였어?
네, 맞습니다. 보통 RAM은 전기가 들어오면 데이터가 유지된다고 생각하죠? 하지만 DRAM은 전기가 공급되고 있어도, 중간에 '리프레시(다시 채우기)' 작업을 안 해주면 순식간에 데이터를 까먹어 버립니다.
컴퓨터 안에 있는 CPU와 메모리 컨트롤러가 우리가 모르는 사이에 1초에 수백 번씩 계속 전기를 다시 채워주고 있는 거예요.
6-2
네, 맞습니다. C언어의 gets() 함수는 보안 역사상 가장 위험한 함수 중 하나로 꼽히는데, 그 이유가 바로 이미지에 나온 '메모리 침범(오버플로우)' 때문입니다.
1. 이미지 상황: "내 땅은 여기까지인데?"
이미지를 보시면 메모장에게 할당된 논리 주소는 0번지부터 999번지까지입니다. 총 1000칸의 공간을 받은 거죠.
- 그런데 CPU가 **"메모장 1500번지에 숫자를 써라!"**라고 명령합니다.
- 만약 이 명령을 그대로 실행하면 어떻게 될까요? 메모장(1000~1999)의 범위를 훌쩍 넘어서, **인터넷 브라우저(2000
~2999)가 쓰고 있는 땅**에 숫자를 적어버리게 됩니다.
- 결과: 인터넷 브라우저가 갑자기 꺼지거나(Crash), 해커가 심어놓은 코드가 실행될 수 있습니다.
2. C언어의 gets()와 오버플로우
C언어의 gets() 함수가 바로 이 사고를 치는 주범입니다.
- 상황: 내가 10글자 들어갈 '그릇(버퍼)'을 만들어 놨습니다.
- 문제: gets()는 사용자가 100글자를 입력하든, 1000글자를 입력하든 묻지도 따지지도 않고 메모리에 다 때려 넣습니다.
- 결과: 10글자 이후의 나머지 90글자는 이미지처럼 **옆집(다른 프로그램이나 시스템 데이터)**의 메모리를 덮어버립니다. 이것이 바로 **버퍼 오버플로우(Buffer Overflow)**입니다.
3. 그래서 '메모리 보호'가 필요합니다
이미지에서 하고 싶은 말은 이겁니다.
"CPU야, 명령 내리기 전에 '한계 레지스터(Limit Register)'를 확인해! 메모장이 999번지까지만 쓰기로 했으면, 1500번지 명령은 거절해야지!"
이걸 막아주는 하드웨어 장치가 **MMU(Memory Management Unit)**이고, 이런 잘못된 접근이 발생했을 때 CPU에 "야! 너 선 넘었어!"라고 알려주는 게 바로 우리가 앞서 배운 '동기 인터럽트(예외)' 중 하나인 **Segmentation Fault(메모리 보호 오류)**입니다.
요약하자면:
- **gets()**는 입력값의 길이를 체크하지 않아서 메모리 선을 넘게 만든다.
- 이게 바로 오버플로우다.
- 이미지처럼 남의 메모리 영역(인터넷 브라우저 등)을 건드리지 못하게 막는 기술이 메모리 보호다.
1. 주소 체계의 이원화: 물리 주소와 논리 주소
메모리의 주소 체계는 크게 두 가지로 나뉩니다.
• 물리 주소(Physical Address): 메모리 입장에서 바라본 주소로, 정보가 실제로 저장된 하드웨어상의 실제 주소를 의미합니다.,
• 논리 주소(Logical Address): CPU와 실행 중인 프로그램 입장에서 바라본 주소입니다. 각 프로그램에는 0번지부터 시작하는 고유한 논리 주소가 부여됩니다.,
2. 왜 주소 체계를 나누었는가?
CPU와 실행 중인 프로그램은 메모리 몇 번지에 무엇이 저장되어 있는지 전부 알 수 없습니다. 그 이유는 다음과 같습니다.
• 메모리에 저장된 값들은 시시때때로 변하기 때문입니다.
• 새로운 프로그램이 언제든 적재되고 실행이 끝난 프로그램은 삭제됩니다.
• 같은 프로그램이라도 실행할 때마다 메모리에 적재되는 주소가 달라지기 때문입니다.,
이러한 문제를 극복하기 위해 물리 주소와는 별개로 프로그램마다 0번지부터 시작하는 논리 주소 체계를 사용하게 된 것입니다. 이에 따라 논리 주소는 여러 프로그램에서 중복될 수 있지만, 실제 하드웨어 주소인 물리 주소는 중복될 수 없습니다.,
3. 주소 변환 장치: MMU (Memory Management Unit)
CPU가 이해하는 주소는 논리 주소이지만, 실제 메모리와 상호작용하기 위해서는 이를 물리 주소로 변환해야 합니다. 이 변환은 CPU와 메모리 사이에 위치한 **MMU(메모리 관리 장치)**라는 하드웨어에 의해 수행됩니다.
주소 변환의 기본 원리:
• MMU는 논리 주소와 베이스 레지스터(Base Register) 값을 더하여 물리 주소로 변환합니다.,
• 베이스 레지스터: 실행 중인 프로그램의 물리 주소상 시작 주소(가장 작은 물리 주소)를 저장합니다.,
• 논리 주소: 프로그램의 시작점(베이스 레지스터 값)으로부터 얼마나 떨어져 있는지를 나타내는 거리(오프셋)와 같습니다.,
• 예를 들어, 베이스 레지스터 값이 15,000이고 논리 주소가 100이라면, 실제 물리 주소는 15,100번지가 됩니다.,
4. 메모리 보호: 한계 레지스터 (Limit Register)
다른 프로그램의 영역을 침범하는 명령어로부터 메모리를 보호하기 위해 한계 레지스터가 사용됩니다.,
• 한계 레지스터의 역할: 실행 중인 프로그램의 논리 주소의 최대 크기를 저장합니다.
• 보호 메커니즘: CPU가 접근하려는 논리 주소가 한계 레지스터 값보다 크면, 이는 다른 프로그램의 영역을 침범하는 것이므로 MMU는 해당 명령어의 실행을 막습니다.,
• 이를 통해 프로그램의 물리 주소 범위는 **'베이스 레지스터 값 이상, 베이스 레지스터 + 한계 레지스터 값 미만'**으로 안전하게 제한됩니다.,
결론적으로, 베이스 레지스터는 프로그램의 시작 위치를 결정하고, 한계 레지스터는 프로그램의 크기를 제한함으로써 각 프로그램이 독립된 공간에서 안전하게 실행되도록 보장합니다.,
1. 왜 굳이 '근처(공간 지역성)'를 찾을까?
프로그램은 생각보다 훨씬 더 순차적으로 움직입니다.
- 배열(Array): 데이터가 메모리에 다닥다닥 붙어 있습니다. a[0]을 읽으면 그다음은 99% 확률로 a[1]을 읽겠죠?
- 명령어 실행: 우리가 코드를 짤 때 위에서 아래로 짜죠? CPU도 1번 줄 명령어를 실행하면, 바로 옆에 있는 2번 줄 명령어를 실행합니다.
- 함수 안에서도 마찬가지: 함수가 멀리 떨어져 있더라도, 일단 그 함수로 **점프(Jump)**한 다음에는 그 안에서 다시 1번 줄, 2번 줄... 순서대로 실행합니다. 즉, 점프하는 순간만 빼면 다시 '근처'를 뒤지게 됩니다.
2. 왜 '최근(시간 지역성)'에 쓴 걸 또 쓸까?
이건 **반복문(Loop)**과 변수 때문입니다.
- 반복문: for 문이나 while 문을 돌리면 똑같은 코드 영역을 수만 번 반복해서 읽습니다. 방금 읽은 그 코드를 0.0001초 뒤에 또 읽어야 하죠.
- 변수: 합계를 구하는 sum = sum + i; 같은 코드를 보면, sum이라는 변수(메모리 공간)를 반복문 내내 계속 가져다 씁니다.
3. 질문하신 "함수는 멀리 떨어져 있지 않나?"에 대한 답변
네, 맞습니다! 함수 호출은 멀리 있는 주소로 순간이동하는 것과 같습니다. 하지만 여기서 중요한 포인트가 있습니다.
- 점프는 가끔 일어난다: CPU가 1억 번의 연산을 한다면, 그중 함수 호출(점프)은 상대적으로 적습니다. 대부분은 반복문 안에서 뱅뱅 돌거나 옆 칸으로 이동하는 연산입니다.
- 스택(Stack) 메모리: 함수가 호출될 때 사용하는 지역 변수들은 메모리의 '스택' 영역에 차곡차곡 쌓입니다. 함수가 멀리 떨어져 있어도, 그 함수가 쓰는 데이터(변수)들은 스택의 아주 좁은 구역에 옹기종기 모여 있게 됩니다. 그래서 '공간 지역성'이 유지됩니다.
CPU는 이 '경향'을 믿고 **캐시 메모리(Cache)**라는 빠른 저장소에 근처 데이터를 미리 갖다 놓습니다. 함수로 점프하는 '예외' 상황보다, 근처를 계속 쓰는 '일반적인' 상황이 훨씬 많기 때문에 이 원리가 컴퓨터를 엄청나게 빠르게 만들어주는 것입니다!
1. 캐시 메모리의 등장 배경과 저장장치 계층 구조
CPU의 연산 속도는 메모리(주기억장치)에 접근하는 속도보다 압도적으로 빠릅니다. 이러한 속도 차이로 인해 발생하는 성능상의 손해를 줄이기 위해 캐시 메모리가 등장했습니다. 이를 이해하기 위해서는 **저장장치 계층 구조(Memory Hierarchy)**라는 개념을 알아야 합니다.
• 저장장치 계층 구조의 원칙:
1. CPU와 가까운 저장장치일수록 속도가 빠르고, 멀리 있는 장치는 느립니다.
2. 속도가 빠른 저장장치일수록 저장 용량이 작고 가격이 비쌉니다.
• 계층 순서: 레지스터 > 캐시 메모리 > 메모리(RAM) > 보조기억장치 순으로 속도가 빠르며, 위로 갈수록 용량은 작아지고 가격은 비싸집니다. 컴퓨터는 이러한 장단점이 명확한 장치들을 계층적으로 배치하여 효율적으로 사용합니다.
2. 캐시 메모리의 정의와 특징
캐시 메모리는 CPU와 메모리 사이에 위치하며, 레지스터보다는 용량이 크고 메모리보다는 속도가 빠른 SRAM 기반의 저장장치입니다.
• 목적: CPU의 연산 속도와 메모리 접근 속도의 차이를 완화하기 위해 사용합니다.
• 비유: 메모리가 물건은 많지만 거리가 멀어 왕복이 오래 걸리는 대형 마트라면, 캐시 메모리는 물건은 적어도 집 근처에 있어 빨리 다녀올 수 있는 편의점과 같습니다. 현대의 대부분 CPU는 성능 향상을 위해 캐시 메모리를 내장하고 있습니다.
3. 계층적 캐시 메모리 (L1, L2, L3)
캐시 메모리 또한 성능과 용량에 따라 계층적으로 구성됩니다.
• L1, L2, L3 캐시: 숫자가 작을수록 CPU와 가깝고 속도가 빠르며 용량이 작습니다. 일반적으로 L1과 L2 캐시는 각 코어 내부에 위치하고, L3 캐시는 코어 외부에서 여러 코어가 공유하는 형태로 설계됩니다.
• 분리형 캐시: L1 캐시의 속도를 극대화하기 위해 명령어만을 담는 **L1I(Instruction)**와 데이터만을 담는 L1D(Data) 캐시로 나누어 관리하기도 합니다.
• 데이터 일관성: 멀리코어 프로세서에서는 각 코어의 캐시가 서로 다른 내용을 저장할 수 있어, 이들의 싱크를 맞추는 데이터 일관성 유지가 매우 중요한 과제입니다.
4. 캐시 메모리의 작동 원리: 참조 지역성의 원리
캐시 메모리는 메모리의 모든 내용을 담을 수 없으므로, CPU가 자주 사용할 법한 데이터를 예측하여 저장합니다.
• 캐시 히트(Cache Hit)와 미스(Cache Miss):
◦ 캐시 히트: CPU가 필요한 데이터가 캐시에 있어 바로 사용하는 경우로, 성능이 높아집니다.
◦ 캐시 미스: 필요한 데이터가 캐시에 없어 메모리에서 직접 가져와야 하는 상황이며, 성능이 떨어집니다.
◦ 캐시 적중률: 전체 메모리 접근 횟수 중 캐시 히트가 발생하는 비율로, 현대 CPU는 보통 80~90% 이상의 높은 적중률을 보입니다.
• 참조 지역성의 원리 (Locality of Reference): 데이터를 예측하는 두 가지 주요 원칙입니다.
1. 시간 지역성: CPU는 최근에 접근했던 메모리 공간에 다시 접근하려는 경향이 있습니다. (예: 반복문에서 사용되는 변수)
2. 공간 지역성: CPU는 접근한 메모리 공간의 근처에 접근하려는 경향이 있습니다. (예: 관련 기능들이 모여 있는 프로그램 데이터)
캐시 메모리는 이 두 가지 원리를 바탕으로 필요한 데이터를 미리 가져옴으로써 컴퓨터의 전반적인 처리 속도를 향상시킵니다.
7-1
1. 보조기억장치의 개요
보조기억장치는 전원이 공급되지 않아도 저장된 내역을 유지할 수 있는 비휘발성 저장장치입니다. 주기억장치인 RAM은 휘발성이라 전원을 끄면 데이터가 사라지기 때문에, 데이터를 영구적으로 보관하기 위해 하드 디스크, SSD, USB, SD 카드 같은 보조기억장치가 필요합니다.
2. 하드 디스크 (HDD)
하드 디스크는 자기적 방식으로 데이터를 저장하여 '자기 디스크'의 일종으로 분류됩니다.
• 주요 구성 요소:
◦ 플래터(Platter): 수많은 N극과 S극으로 데이터가 저장되는 동그란 원판입니다. 보통 여러 겹으로 이루어져 있으며 양면을 모두 사용합니다.
◦ 스핀들(Spindle): 플래터를 회전시키는 장치로, 회전 속도 단위는 RPM(1분당 회전수)을 사용합니다.
◦ 헤드(Head): 플래터 위를 아주 미세하게 떠서 자기 물질을 읽고 쓰는 장치입니다.
◦ 디스크 암(Disk Arm): 헤드를 움직이는 구성 요소로, 일반적으로 모든 헤드가 디스크 암에 부착되어 동시에 이동합니다.
• 저장 단위:
◦ 트랙(Track): 플래터의 동심원 저장 단위입니다.
◦ 섹터(Sector): 트랙을 여러 조각으로 나눈 최소 저장 단위입니다. 하나 이상의 섹터를 묶어 **블록(Block)**이라 부르기도 합니다.
◦ 실린더(Cylinder): 여러 겹의 플래터에서 같은 트랙이 위치한 곳을 논리적으로 연결한 원통 모양의 단위입니다. 헤드를 움직이지 않고도 데이터를 곧바로 읽을 수 있어, 보통 연속된 정보는 한 실린더에 기록됩니다.
• 접근 시간(Access Time): 하드 디스크에서 데이터를 읽거나 쓰는 시간은 다음 세 가지의 합으로 결정됩니다:
1. 탐색 시간(Seek Time): 헤드를 해당 트랙까지 이동시키는 시간입니다.
2. 회전 지연(Rotational Latency): 플래터를 회전시켜 원하는 섹터가 헤드 밑으로 오게 하는 시간입니다.
3. 전송 시간(Transfer Time): 하드 디스크와 컴퓨터 간에 데이터를 실제로 전송하는 시간입니다. 이 시간들은 CPU나 메모리의 동작 속도에 비해 굉장히 긴 시간이며, 성능에 큰 영향을 주는 주요 변수입니다.
3. 플래시 메모리 (Flash Memory)
플래시 메모리는 전기적 방식으로 데이터를 읽고 쓰는 반도체 기반 저장장치로, SSD, SD 카드, USB 등에 사용됩니다. 보조기억장치뿐만 아니라 주기억장치인 ROM으로도 활용되는 등 범용성이 넓습니다.
• 종류: 대용량 저장장치에는 주로 낸드(NAND) 플래시 메모리가 사용됩니다.
• 셀(Cell) 타입에 따른 분류: 한 셀에 몇 비트를 저장하느냐에 따라 수명, 가격, 성능이 달라집니다.
◦ SLC (Single Level Cell): 한 셀에 1비트 저장. 입출력이 가장 빠르고 수명이 길지만 가격이 비쌉니다.
◦ MLC (Multi Level Cell): 한 셀에 2비트 저장. SLC보다 속도는 느리고 수명은 짧지만 대용량화에 유리하고 가격이 저렴합니다.
◦ TLC (Triple Level Cell): 한 셀에 3비트 저장. MLC보다도 속도와 수명이 떨어지지만 용량 대비 가격이 가장 저렴하여 시중에서 많이 사용됩니다.
◦ QLC (Quadruple Level Cell): 한 셀에 4비트를 저장하는 방식도 존재합니다.
• 저장 단위와 동작 특성:
◦ 단위: 셀(Cell) < 페이지(Page) < 블록(Block) < 플레인(Plane) < 다이(Die) 순으로 구성됩니다.
◦ 읽기와 쓰기는 '페이지' 단위로 이루어지지만, 삭제는 '블록' 단위로 이루어지는 것이 특징입니다.
◦ 플래시 메모리는 하드 디스크와 달리 덮어쓰기가 불가능합니다.
• 가비지 컬렉션 (Garbage Collection): 플래시 메모리의 페이지 상태는 데이터 유무에 따라 Free(비어있음), Valid(유효함), **Invalid(유효하지 않음 - 쓰레기 값)**로 나뉩니다. 덮어쓰기가 안 되기 때문에 기존 데이터를 수정하면 기존 페이지를 Invalid 상태로 만들고 새 페이지에 데이터를 씁니다. 이로 인해 발생하는 용량 낭비를 막기 위해, 유효한(Valid) 페이지만 새 블록으로 복사한 뒤 기존 블록을 삭제하여 공간을 확보하는 기술을 가비지 컬렉션이라고 합니다.
추가 참고: 하드 디스크와 플래시 메모리 모두 일정 횟수 이상 데이터를 쓰고 지우면 수명을 다하게 되는 소모성 부품입니다
1. 연필과 자석(HDD) vs 볼펜과 종이(플래시 메모리)
- 하드 디스크(HDD): 자석과 같습니다. N극을 S극으로 바꾸듯, 그냥 그 자리에 새로운 자기 신호를 입히면 끝입니다. (연필로 쓴 걸 지우고 그 자리에 바로 다시 쓰는 것과 비슷합니다.)
- 플래시 메모리(SSD): 종이에 볼펜으로 글자를 쓰는 것과 같습니다. 이미 써진 글자 위에 다른 글자를 덧쓰면 글자가 뭉쳐서 알아볼 수 없게 되죠? 그래서 반드시 **'지우개로 깨끗이 지운 상태(Free)'**에서만 글자를 새로 쓸 수 있습니다.
2. 왜 그냥 못 지우나요? (페이지와 블록의 문제)
여기서 플래시 메모리만의 독특한 제약이 생깁니다.
- 읽기/쓰기 단위: 페이지(Page) — 아주 작은 단위입니다.
- 삭제 단위: 블록(Block) — 페이지 수백 개가 모인 큰 묶음입니다.
플래시 메모리는 구조상 글씨는 '페이지' 단위로 쓸 수 있지만, 지우는 건 '블록' 단위로만 가능합니다.
예를 들어, 한 페이지의 내용만 수정하고 싶어도 그 페이지가 포함된 블록 전체(수백 페이지)를 통째로 지워야만 그 자리에 다시 쓸 수 있는 공간이 생깁니다. 만약 매번 덮어쓰기를 하려고 블록 전체를 지웠다 썼다 하면 속도가 엄청나게 느려지고 수명도 금방 닳게 됩니다.
3. 그래서 선택한 방법: "일단 다른 데다 쓸게!"
플래시 메모리는 덮어쓰기가 안 되기 때문에 다음과 같은 방식을 사용합니다.
- 기존 데이터 무효화: 원래 있던 데이터(A)를 수정하고 싶으면, 그 자리에 덮어쓰는 게 아니라 기존 데이터를 **'Invalid(쓰레기)'**라고 표시해버립니다.
- 새 데이터 기록: 비어있는 다른 공간(Free 페이지)에 수정된 데이터(A')를 새로 씁니다.
- 청소(가비지 컬렉션): 이렇게 쓰레기(Invalid)가 쌓이다가 용량이 부족해지면, 나중에 한꺼번에 블록을 비워서 진짜 빈 공간으로 만듭니다.
요약하자면
플래시 메모리는 **"전기적으로 데이터를 지우는 과정이 쓰기 과정보다 훨씬 크고 복잡(블록 단위)"**하기 때문에, 효율성을 위해서 바로 덮어쓰지 않고 비어 있는 곳에 새로 쓰고 기존 것은 버리는 방식을 택한 것입니다.
이 과정 때문에 본문에 나온 **'가비지 컬렉션'**이라는 복잡한 관리 기술이 꼭 필요한 것이기도 합니다!
| 구분 |
플래시 메모리 GC (하드웨어) |
자바 GC (소프트웨어) |
| 장소 |
보조기억장치 (SSD, USB 등) |
주기억장치 (RAM) |
| 대상 |
수명이 다한 '페이지' (Invalid Page) |
참조가 끊긴 '객체' (Unreachable Object) |
| 발생 이유 |
물리적 한계 (덮어쓰기가 안 되기 때문) |
메모리 관리 편의성 (개발자가 일일이 메모리를 해제하지 않게 하려고) |
| 수행 주체 |
SSD 내부의 컨트롤러 (Firmware) |
자바 가상 머신 (JVM) |
7-2
1. 레이드(RAID)의 정의
**레이드(Redundant Array of Independent Disks)**란 하드디스크나 SSD와 같은 여러 개의 물리적인 보조기억장치를 마치 하나의 논리적인 보조기억장치처럼 사용하는 기술을 의미합니다. 이 기술을 통해 데이터를 더 안전하게 보관하거나, 단일 디스크를 사용할 때보다 더 높은 성능을 낼 수 있습니다. 레이드를 구성하는 방법은 다양하며, 이를 **'레이드 레벨'**이라고 부릅니다.
2. 주요 레이드 레벨별 특징
• RAID 0 (스트라이핑): 데이터를 단순히 나누어서 여러 디스크에 번갈아 가며 저장하는 방식입니다. 이때 줄무늬처럼 분산되어 저장된 데이터를 **'스트라이프(Stripe)'**라고 하며, 이렇게 저장하는 과정을 **'스트라이핑(Striping)'**이라고 합니다.
◦ 장점: 데이터를 동시에 읽고 쓸 수 있어 입출력 속도가 매우 빠릅니다.
◦ 단점: 저장된 정보가 안전하지 않습니다. 디스크 하나만 고장 나도 전체 데이터를 사용할 수 없게 됩니다.
• RAID 1 (미러링): 마치 거울처럼 데이터의 완전한 복사본을 만드는 방식입니다. 원본과 동일한 내용을 다른 디스크에 백업하므로 안전성이 높습니다.
◦ 장점: 복사본이 존재하기 때문에 백업과 복구가 매우 쉽고 안전합니다.
◦ 단점: 똑같은 데이터를 두 번 써야 하므로 쓰기 속도가 느릴 수 있으며, 가용 용량이 절반으로 줄어들어 비용이 증가합니다.
• RAID 4 (패리티 디스크): 오류를 검출하고 복구하기 위한 정보인 **'패리티 비트(Parity bit)'**를 별도의 디스크 한 개에 몰아서 저장하는 방식입니다.
◦ 특징: 레이드에서의 패리티 비트는 일반적인 오류 검출뿐만 아니라 오류 복구까지 가능하게 해줍니다.
◦ 단점: 데이터를 쓸 때마다 패리티 디스크를 매번 업데이트해야 하므로 해당 디스크에 부하가 몰리는 병목 현상이 발생할 수 있습니다.
• RAID 5 (분산 패리티): RAID 4의 병목 현상을 해결하기 위해 패리티 정보를 여러 디스크에 분산하여 저장하는 방식입니다. 이를 통해 특정 디스크에만 입출력이 집중되는 문제를 완화합니다.
• RAID 6: RAID 5와 유사하지만, 두 가지 종류의 패리티를 사용하는 방식입니다.
◦ 장점: 두 종류의 오류 검출 및 복구 수단을 두어 RAID 5보다 훨씬 안전하게 정보를 저장할 수 있습니다.
◦ 단점: 두 종류의 패리티를 계산하고 저장해야 하므로 RAID 5보다 쓰기 속도는 더 느릴 수 있습니다.
3. 요약 및 실무 적용
최적의 레이드 레벨은 사용자가 무엇을 최우선으로 하느냐에 따라 달라집니다. 빠른 성능이 중요하다면 RAID 0이 적합하고, 데이터의 안전성이 최우선이라면 RAID 1이나 6을 선택하는 것이 좋습니다.
이러한 레이드 기술은 단순히 이론에 그치지 않고, 실제 컴퓨터의 BIOS 설정 등을 통해 RAID 0 스트라이핑 크기를 지정하는 등 사용자가 직접 구성하여 실무에서 활용할 수 있는 기술입니다. 또한, 소스에서는 언급된 레벨 외에도 이들로부터 파생된 네스티드 레이드(Nested RAID) 등 더 다양한 종류가 존재한다고 설명합니다.
- RAID 5: 디스크 1개가 고장 날 때까지만 버틸 수 있습니다. (2개가 동시에 고장 나면 데이터가 다 날아갑니다.)
- RAID 6: 디스크 2개가 동시에 고장 나도 데이터를 안전하게 복구할 수 있습니다.
2. 왜 이런 차이가 생기나요? (패리티의 개수)
본문에 나온 '패리티(오류 복구 정보)'를 몇 종류 만드느냐에 따라 달라집니다.
- RAID 5 (분산 패리티): 패리티 정보를 1세트만 만듭니다. 이 패리티를 여러 디스크에 나눠 저장하죠. 그래서 디스크 1개 분량의 용량을 복구용으로 사용하게 됩니다.
- RAID 6 (이중 분산 패리티): 서로 다른 방식의 패리티를 2세트 만듭니다. "A 방식 패리티"와 "B 방식 패리티" 두 개가 있으니, 디스크 두 개가 고장 나도 각각의 패리티를 조합해 데이터를 살려낼 수 있습니다. 대신 디스크 2개 분량의 용량을 복구용으로 사용합니다.
8-1
인터넷은 "출렁"거립니다 (속도의 불안정성)
만약 인터넷이 단 0.1초도 쉬지 않고 정확하게 1초에 1초 분량씩 데이터를 보내준다면, 버퍼링(쌓아두기)은 필요 없을지도 모릅니다.
하지만 실제 와이파이나 LTE는 이렇습니다.
- 0~1초 사이: 2초 분량 들어옴 (오! 빠름)
- 1~2초 사이: 0초 분량 들어옴 (갑자기 끊김)
- 2~3초 사이: 1초 분량 들어옴
만약 버퍼(창고)에 쌓아두지 않고 오는 족족 바로 재생한다면, 1~2초 사이에서 데이터가 안 올 때 영상이 '툭' 하고 멈춰버리겠죠?
2버퍼링이 주는 "여유 시간" (안전빵)
그래서 유튜브는 영상을 시작할 때 바로 틀지 않고, 처음 몇 초 동안 데이터를 미리 창고(버퍼)에 꽉꽉 채웁니다. (우리가 처음에 뱅글뱅글 돌아가는 걸 기다리는 이유입니다.)
- 창고에 5초 분량이 쌓여있다고 가정해 봅시다.
- 이때 인터넷이 갑자기 불안해져서 3초 동안 아예 데이터를 못 가져와도,
- 내 폰은 창고에 이미 들어와 있는 5초 치 데이터를 꺼내서 계속 보여줍니다.
- 사용자는 인터넷이 끊겼다는 사실조차 모르고 영상을 계속 보게 되는 거죠!
3. "버퍼에 있는 건 인터넷이랑 상관없나?"
네, 맞습니다! 일단 버퍼(내 폰의 메모리)에 들어온 데이터는 이제 인터넷 연결과는 상관이 없습니다.
이미 내 폰이라는 '창고' 안에 들어와 있는 상태니까요. 그래서 비행기 모드를 켜더라도, 이미 버퍼링(미리 받기) 된 몇 초~몇 십 초 분량의 영상은 끊기지 않고 나오는 것을 볼 수 있습니다.
1. 입출력장치를 다루기 어려운 이유
입출력장치는 CPU나 메모리에 비해 다루기가 까다로운데, 여기에는 두 가지 주요 이유가 있습니다.
• 종류의 다양성: 장치의 종류가 너무 많고 제조사마다 데이터 전송 형식이나 속도가 제각각이라 방식을 규격화하기 어렵습니다,.
• 전송률의 차이: 일반적으로 CPU와 메모리는 데이터를 매우 빨리 교환(높은 전송률)하는 반면, 입출력장치는 상대적으로 전송 속도가 느립니다,.
2. 장치 컨트롤러 (Hardware)
입출력장치의 까다로운 점을 해결하기 위해 등장한 하드웨어가 장치 컨트롤러(입출력 제어기/모듈)입니다. 모든 입출력장치는 하나 이상의 장치 컨트롤러와 연결되어 컴퓨터 내부와 소통합니다.
• 주요 역할:
1. 통신 중개: CPU와 입출력장치 사이에서 '번역가' 역할을 수행하여 정보 규격화 문제를 해결합니다,.
2. 오류 검출: 연결된 장치에 문제가 없는지 확인합니다,.
3. 데이터 버퍼링: 전송률이 높은 장치와 낮은 장치 사이의 데이터를 **버퍼(임시 저장 공간)**에 저장하여 속도 차이를 완화합니다,.
• 내부 구조(레지스터): 장치 컨트롤러는 버스에 연결되어 정보를 주고받으며, 내부에 세 가지 주요 레지스터를 가집니다.
◦ 데이터 레지스터: 주고받을 데이터가 담기며 버퍼 역할을 합니다.
◦ 상태 레지스터: 장치의 준비 상태, 작업 완료 여부, 오류 유무 등의 정보를 저장합니다.
◦ 제어 레지스터: 장치가 수행할 내용에 대한 제어 정보를 담습니다.
3. 장치 드라이버 (Software)
장치 컨트롤러가 하드웨어적 통로라면, 장치 드라이버는 이를 동작시키고 제어하는 **프로그램(소프트웨어적 통로)**입니다.
• 역할: 새로운 장치를 컴퓨터에 연결했을 때, CPU가 해당 장치의 컨트롤러를 어떻게 조작해야 하는지 알려주는 역할을 합니다.
• 중요성: 드라이버가 설치되어 있어야만 컴퓨터가 해당 장치를 인식하고 사용할 수 있습니다.
• 실행 주체: 장치 드라이버를 인식하고 실행하는 실질적인 주체는 **운영체제(OS)**입니다.
1. 장치 드라이버 = "장치 전용 매뉴얼"
이미지 설명처럼 장치 드라이버는 컴퓨터(CPU)에게 "이 프린터는 이렇게 다루는 거야"라고 알려주는 소프트웨어 매뉴얼입니다. 이 매뉴얼(코드)은 메모리에 저장되어 있습니다.
2. 인터럽트 = "매뉴얼을 펼치게 만드는 호출 벨"
CPU가 다른 일을 열심히 하고 있는데, 프린터가 인쇄를 다 끝냈거나 종이가 걸렸다면 CPU에게 알려야겠죠? 이때 누르는 벨이 인터럽트입니다.
3. 유저님이 기억하신 그 과정 (연결고리)
질문하신 "해당 주소로 가서 해결하고 복귀하는 과정"이 바로 여기서 일어납니다.
- 인터럽트 발생: 프린터가 "저기요!" 하고 신호를 보냅니다.
- 주소 찾기 (인터럽트 벡터): CPU는 미리 약속된 표를 보고, 이 문제를 해결할 '매뉴얼(장치 드라이버)'이 메모리 어느 주소에 있는지 찾습니다.
- 해당 주소로 이동 (실행): CPU는 하던 일을 멈추고, 그 주소로 가서 **장치 드라이버에 적힌 해결 방법(인터럽트 서비스 루틴)**을 읽고 실행합니다. (이게 유저님이 말씀하신 '매뉴얼대로 해결'하는 단계입니다.)
- 원래 주소로 복귀: 해결이 끝나면, 아까 멈췄던 원래 작업 위치로 돌아가서 하던 일을 계속합니다.
요약하자면!
- 장치 드라이버는 메모리에 저장된 '행동 지침서(매뉴얼)' 그 자체이고,
- 인터럽트는 그 지침서가 있는 **'주소로 CPU를 점프하게 만드는 신호'**입니다.
8-2