워밍업 클럽 CS 3주차 발자국 : 운영체제
가상 메모리
가상 메모리 개요
가상 메모리는 부족한 물리 메모리를 효율적으로 사용하기 위한 기술로, 메모리 관리자가 가상 주소를 물리 주소에 매핑하여, 실제 물리 메모리보다 더 큰 메모리 공간을 사용할 수 있게 합니다. 이를 통해 각 프로세스는 독립적인 메모리 공간을 가지며, 안정성과 보안을 높입니다.
개발자는 물리 메모리의 크기나 위치에 신경 쓰지 않고, 0x0 번지에서 시작한다고 생각하며 프로그래밍할 수 있습니다. 실제 메모리 접근은 메모리 관리자가 처리하며, 프로세스는 물리 메모리에 직접 접근하지 않습니다.
가상 메모리의 크기는 CPU의 비트 수에 따라 결정됩니다. 예를 들어, 32비트 CPU는 4GB의 가상 메모리 공간을 제공합니다. 물리 메모리가 부족할 때는, 일부 내용을 하드디스크의 스왑 영역으로 옮겨 필요한 경우 다시 가져와 실행합니다. 이 과정을 동적 주소 변환이라 부르며, 이를 통해 물리 메모리 부족 문제를 해결할 수 있습니다.
메모리 관리는 가상 주소를 물리 주소로 변환하고, 프로세스의 메모리 배치, 스왑 영역 처리 등 복잡한 과정을 수행합니다. 물리 메모리 0번지는 운영체제에 할당되며, 프로세스는 사용할 수 없습니다.
가상 메모리 시스템에서는 메모리를 고정 크기로 나누어 프로세스에 할당하는 페이징과, 가변 크기로 할당하는 세그멘테이션 방식을 사용합니다. 페이징은 내부 단편화, 세그멘테이션은 외부 단편화의 단점이 있으며, 이를 보완한 세그멘테이션-페이징 혼용 기법이 사용됩니다. 가상 주소는 메모리나 스왑 영역에 위치하며, 메모리 관리자는 가상 주소와 물리 주소를 1대1로 매핑해 관리합니다
배치 정책
세그멘테이션
세그멘테이션은 가변 분할 방식을 사용하여 메모리를 분할하는 기법입니다. 프로그램은 함수나 모듈 등으로 나뉘며, 각각의 세그먼트가 생성됩니다. 예를 들어, 메인 코드, 전역 데이터, 힙, 스택 등의 영역이 각각 독립적인 세그먼트로 구성됩니다. 이 세그먼트들은 물리 메모리에서 서로 인접하지 않아도 되지만, 프로세스는 이를 인접한 것처럼 인식합니다.
프로세스와 CPU가 바라보는 논리 주소는 실제 메모리 주소와 다르며, 이를 물리 주소로 변환하는 역할은 메모리 관리자(MMU)가 수행합니다. MMU는 세그멘테이션 테이블을 사용하여 논리 주소를 물리 주소로 변환합니다. 이 테이블에는 베이스 주소(Base Address)와 바운드 주소(Bound Address) 정보가 포함되어 있습니다.
논리 주소가 주어지면, 메모리 관리자는 해당 논리 주소가 속하는 세그먼트를 찾고, 세그멘테이션 테이블에서 해당 세그먼트의 베이스와 바운드 주소를 참조하여 물리 주소를 계산합니다. 논리 주소가 바운드 주소 범위 내에 있으면 베이스 주소와 더해져 물리 주소가 계산되며, 범위를 초과하면 메모리 침범 오류를 발생시켜 해당 프로세스를 종료합니다.
예시 1: CPU가 세그먼트 1번의 논리 주소 0x632로 접근
메모리 관리자가 세그먼트 1번을 확인
세그멘테이션 테이블에서 1번 세그먼트의 베이스 주소(5200)를 찾음
논리 주소(632)와 바운드 주소(1000)를 비교하여 범위 내임을 확인
논리 주소와 베이스 주소를 더해 물리 주소 5832로 변환
예시 2: CPU가 세그먼트 3번의 논리 주소 750으로 접근
메모리 관리자가 세그먼트 3번을 확인
논리 주소(750)가 바운드 주소(500)를 초과하므로 메모리 침범 오류 발생
프로세스가 종료됨
세그멘테이션의 장점은 메모리를 가변적으로 나눌 수 있어 코드, 데이터, 스택, 힙 영역을 모듈로 처리할 수 있고, 각 영역에 대한 접근 보호와 공유가 용이하다는 점입니다. 반면, 단점은 가변 분할 방식에서 발생하는 외부 단편화입니다.
페이징
페이징은 메모리 관리를 위한 고정 분할 방식으로, 외부 단편화 문제를 해결하기 위해 고안되었습니다. 페이징에서는 메모리를 일정한 크기의 페이지로 나누어 할당합니다. 모든 페이지의 크기가 동일하기 때문에 관리가 용이하며, 외부 단편화가 발생하지 않습니다. 대신, 페이지 크기보다 작은 데이터를 저장할 때는 내부 단편화가 발생할 수 있습니다.
논리주소와 물리주소
논리주소공간: 사용자와 프로세스가 바라보는 주소 공간
물리주소공간: 실제 메모리에서 사용되는 주소 공간
논리주소공간과 물리주소공간은 일정한 크기의 페이지와 프레임으로 나뉘며, 두 공간은 매칭됩니다.
주소 변환 과정
페이징에서도 메모리 관리자는 페이지 테이블을 사용해 논리주소를 물리주소로 변환합니다. 논리주소가 전달되면, 메모리 관리자는 해당 논리주소가 몇 번 페이지에 속하는지 확인하고, 페이지 번호와 오프셋을 이용해 물리주소를 계산합니다.
논리주소에서 페이지 번호를 추출: 페이지 테이블의 인덱스 역할
해당 인덱스를 참조해 프레임 번호를 가져옴
오프셋을 더해 최종 물리주소로 변환
페이징에서 페이지 테이블에 "invalid"로 표시된 페이지는 스왑 영역(하드디스크)에 저장되어 있다는 의미입니다.
또한, 컨텍스트 스위칭 시, 운영체제는 페이지 테이블을 해당 프로세스에 맞게 업데이트해야 합니다.
32비트 CPU 주소 변환 예시
가상 메모리의 크기는 약 4GB (2^32 바이트)
가상 메모리를 16MB(2^24 바이트) 페이지로 나누면, 24비트는 페이지 크기, 나머지 8비트는 페이지 번호를 나타냅니다. 즉, 총 256개의 페이지가 존재하게 됩니다.
물리 메모리는 가상 메모리와 동일한 크기로 페이지로 나뉘지만, 물리 주소 공간이 더 작아도 문제가 없습니다. 부족한 메모리는 스왑 처리로 해결되기 때문입니다.
주소 변환 예시 1: 논리주소 1000번지
페이지 번호: 1000 / 16777216 = 0
오프셋: 1000 % 16777216 = 1000
페이지 테이블의 0번 인덱스를 참조해 프레임 3을 가져오고, 오프셋을 더해 물리주소를 구함.
주소 변환 예시 2: 논리주소 31554432번지
페이지 번호: 31554432 / 16777216 = 1
오프셋: 31554432 % 16777216 = 14777216
페이지 테이블의 1번 인덱스를 참조해 프레임 1을 찾아 물리주소로 변환.
페이징과 세그멘테이션의 차이
페이지 크기: 페이징은 고정된 크기의 페이지를 사용하며, 세그멘테이션은 프로세스마다 다른 크기의 세그먼트를 가짐.
단편화: 페이징에서는 내부 단편화가 발생하고, 세그멘테이션에서는 외부 단편화가 발생합니다.
메모리 접근 방식: 세그멘테이션은 코드, 데이터, 스택, 힙 등 논리적 영역에 맞춰 나누지만, 페이징은 고정된 크기의 페이지로 나누기 때문에 특정 영역을 떼어내서 공유하거나 권한을 부여하기 어렵습니다.
페이징의 한계
페이징에서 가장 신경 써야 하는 점은 페이지 테이블의 크기입니다. 각 프로세스는 고유한 페이지 테이블을 가지며, 프로세스 수가 많아질수록 페이지 테이블이 차지하는 메모리 공간도 증가합니다. 메모리 관리자 역시 물리 메모리 내의 운영체제 영역에 페이지 테이블을 저장하기 때문에, 페이지 테이블이 커지면 사용자 영역의 메모리가 부족해질 수 있습니다.
따라서 페이지 테이블의 크기를 적절하게 유지하는 것이 매우 중요합니다.
페이지드 세그멘테이션
페이지드 세그멘테이션은 세그멘테이션과 페이징의 장점을 결합한 메모리 관리 방식입니다. 세그멘테이션은 영역별로 메모리를 관리하고, 페이징은 메모리를 일정 크기로 나누어 관리 효율성을 높입니다. 이 방식은 두 기법의 이점을 활용할 수 있지만, 새로운 단점도 존재합니다.
장점
세그멘테이션의 가변 분할 방식을 사용해 프로세스의 코드, 데이터, 스택, 힙 영역을 독립적으로 관리 가능. 각 영역에 대해 메모리 접근 보호 및 공유가 용이합니다.
페이징의 고정 분할 방식을 통해 메모리를 효율적으로 관리하고 외부 단편화를 줄일 수 있습니다.
단점
이 기법의 단점은 메모리 접근이 두 번 이루어진다는 점입니다:
세그멘테이션 테이블을 참조하여 세그멘트 정보를 가져올 때
페이지 테이블을 참조하여 페이지 정보를 가져올 때
이중 접근으로 인한 오버헤드가 발생할 수 있습니다.
메모리 접근 권한
각 프로세스는 영역별로 읽기, 쓰기, 실행 권한이 다르게 부여됩니다:
코드 영역: 읽기와 실행 권한만 있고, 수정이 불가능합니다.
데이터 영역: 읽기와 쓰기 권한이 있으며, 실행 권한은 없습니다.
스택 & 힙 영역: 읽기와 쓰기 권한이 있으나 실행 권한은 없습니다.
이 권한은 가상 주소를 물리 주소로 변환할 때마다 확인되며, 만약 권한 위반이 발생하면 에러를 발생시키고 프로세스를 종료시킵니다.
페이지드 세그멘테이션의 주소 변환 과정
세그멘트 번호를 가상 주소에서 추출하여 해당 세그먼트에 대한 메모리 접근 권한을 확인합니다.
권한이 적합하면, 세그멘트에서 페이지 번호와 페이지 개수를 가져옵니다.
페이지 번호로 페이지 테이블에 접근하여 해당 프레임 번호를 찾습니다.
물리 메모리의 프레임에 접근해 오프셋을 더하여 최종 물리 주소를 계산합니다.
만약 해당 프레임이 물리 메모리에 없다면, 스왑 영역에서 불러옵니다.
현대 운영체제는 페이징과 페이지드 세그멘테이션을 상황에 맞게 혼합하여 사용하고 있습니다. 페이지드 세그멘테이션의 장점은 두 기법의 이점을 취해 메모리 관리의 유연성과 효율성을 높이는 반면, 오버헤드로 인한 성능 저하를 피하기 위해 적절한 균형을 유지하는 것이 중요합니다.
가져오기 정책
디멘드 페이징 정책
디멘드 페이징은 프로세스 실행 시 필요한 데이터만 메모리에 올려서 실행하는 방식으로, 메모리 효율을 극대화하는 가져오기 정책입니다. 이 방법은 프로세스의 모든 데이터가 처음부터 메모리에 로드되지 않고, 필요한 시점에만 가져오므로 메모리 자원을 아낄 수 있습니다.
지역성 이론과 디멘드 페이징
90:10 법칙에 따르면 프로그램은 90%의 시간을 10%의 코드에서 소모합니다. 이 원리를 지역성 이론으로 설명할 수 있는데, 지역성 이론에는 두 가지 중요한 개념이 있습니다:
시간적 지역성: 최근에 접근한 데이터는 다시 접근할 가능성이 높다.
공간적 지역성: 현재 접근한 데이터와 가까운 위치에 있는 데이터가 곧 접근될 가능성이 높다.
디멘드 페이징은 이 이론을 바탕으로, 메모리에서 당장 필요하지 않은 데이터는 스왑 영역으로 보내고, 필요할 것 같은 데이터만 메모리에 올리는 정책입니다.
메모리 계층 구조
레지스터: CPU 내에서 가장 빠른 메모리.
캐시 메모리: CPU에서 비교적 가까운 메모리로, 빠른 속도로 접근 가능.
메인 메모리: 데이터 접근이 캐시보다 느리지만 대용량 데이터를 저장.
보조저장장치 (스왑 영역): 메모리보다 훨씬 느리지만 데이터를 저장하는 데 사용됨.
스왑 인/스왑 아웃
스왑 인: 보조저장장치(스왑 영역)에 있던 데이터를 물리 메모리로 가져오는 과정.
스왑 아웃: 물리 메모리에 있는 데이터를 보조저장장치(스왑 영역)로 내보내는 과정.
운영체제는 효율적인 메모리 관리를 위해 스왑 인/스왑 아웃을 최소화하려고 합니다.
페이지 테이블과 비트
프로세스가 가상 메모리에 접근할 때 운영체제는 페이지 테이블을 통해 물리 메모리와 스왑 영역 간의 데이터를 관리합니다. 페이지 테이블의 각 항목은 페이지 엔트리(PTE)라고 불리며, 여러 가지 비트를 포함하고 있습니다:
접근 비트: 페이지가 메모리에 올라온 후에 접근되었는지 나타냅니다.
변경 비트: 페이지의 데이터가 변경되었는지 나타냅니다.
유효 비트: 페이지가 물리 메모리에 있는지 스왑 영역에 있는지 알려줍니다.
읽기/쓰기/실행 비트: 페이지에 대한 접근 권한을 정의합니다.
Page Fault와 프로세스 대기
프로세스가 가상 메모리에 접근하려 할 때, 만약 요청한 페이지가 물리 메모리에 없으면 Page Fault라는 인터럽트가 발생합니다. 이때 운영체제는 스왑 영역에 접근하여 필요한 페이지를 물리 메모리로 가져오고, 프로세스는 대기 상태로 전환됩니다. 이후 페이지가 메모리에 올라가면 프로세스는 다시 실행됩니다.
3가지 상황에서의 처리 과정
스왑이 필요 없는 경우: 요청된 페이지가 이미 물리 메모리에 있으면 즉시 데이터에 접근할 수 있습니다.
스왑 영역에 있는 데이터를 참조하는 경우: 요청된 페이지가 스왑 영역에 있으면 물리 메모리로 데이터를 가져와서 사용합니다.
물리 메모리가 꽉 찬 경우: 새로운 페이지를 가져오기 전에, 현재 물리 메모리에서 사용하지 않는 페이지를 스왑 영역으로 옮겨 공간을 확보합니다.
디멘드 페이징은 지역성 이론에 기반하여 메모리 자원을 효율적으로 사용하는 기법입니다. 메모리 관리자는 페이지 교체 알고리즘을 통해 스왑 인/아웃을 최적화하고 성능을 유지하려고 합니다.
페이지 교체 정책
페이지 교체 정책은 메모리 공간이 부족할 때 어떤 페이지를 선택해 스왑 영역으로 보낼지를 결정하는 중요한 알고리즘입니다. 이 과정에서 페이지 폴트가 발생하며, 메모리에 새로운 페이지를 불러오려면 기존의 페이지를 교체해야 하는 상황이 생깁니다. 페이지 교체 정책은 주로 프로그램의 지역성 원칙을 바탕으로 하며, 다양한 알고리즘들이 존재합니다.
주요 페이지 교체 정책
1. 무작위 선택 (Random)
- 랜덤하게 페이지를 선택해 교체합니다.
- 지역성 이론을 고려하지 않기 때문에 성능이 좋지 않으며, 거의 사용되지 않습니다.
2. FIFO (First In, First Out)
- 가장 먼저 메모리에 들어온 페이지를 먼저 내보내는 방식입니다.
- 구현이 간단하지만, 자주 사용되는 페이지도 교체될 수 있다는 단점이 있습니다.
- FIFO는 페이지 폴트를 줄이려고 메모리를 늘렸을 때, 오히려 페이지 폴트가 증가하는 빌레이디의 역설이 발생할 수 있습니다.
3. Optimum (OPT)
- 앞으로 가장 오랫동안 사용되지 않을 페이지를 교체하는 방식입니다.
- 이론적으로 최적의 방법이지만, 앞으로의 메모리 접근을 예측할 수 없기 때문에 실제로 구현하기는 어렵습니다.
4. LRU (Least Recently Used)
- 가장 최근에 사용되지 않은 페이지를 교체하는 방식입니다.
- 시간의 지역성에 기반하여, 최근에 사용된 페이지가 다시 사용될 확률이 높다는 가정에 따라 작동합니다.
- 실제로 많이 사용되는 알고리즘이며, 성능이 우수하지만 구현이 복잡하고 추가적인 하드웨어 지원이 필요할 수 있습니다.
LRU와 유사한 알고리즘
1. Clock Algorithm (클락 알고리즘)
- LRU의 구현 복잡성을 해결하기 위해 고안된 방식입니다.
- 페이지의 접근 비트를 사용하여, 일정 시간 동안 참조된 페이지인지 아닌지를 판단합니다.
- 클락 핸드가 시계 방향으로 움직이며, 접근 비트가 0인 페이지를 교체 대상으로 선택합니다.
- Enhanced Clock Algorithm은 접근 비트 외에 변경 비트까지 고려하여 성능을 더 향상시킵니다.
2. Second Chance Algorithm (2차 기회 알고리즘)
- FIFO 방식의 문제점을 보완하기 위해, 자주 사용되는 페이지에 두 번째 기회를 주는 방식입니다.
- FIFO 큐에서 페이지가 교체 대상이 될 때, 해당 페이지가 최근에 참조된 경우 큐의 맨 뒤로 이동시켜 수명을 연장시킵니다.
선택적 사용
시스템 하드웨어가 LRU 구현을 지원하지 않으면 FIFO를 사용할 수밖에 없는 경우가 있습니다. 이때는 성능 향상을 위해 2차 기회 알고리즘이나 다른 보완 기법들을 사용할 수 있습니다.
결론적으로, LRU는 가장 좋은 성능을 보이는 경우가 많지만, 구현 복잡성을 고려해 Clock Algorithm 같은 유사 알고리즘이 더 자주 사용됩니다.
스레싱과 워킹셋
스레싱(Thrashing)은 CPU 사용률을 높이기 위해 멀티 프로그래밍 정도를 지나치게 높였을 때 발생하는 문제로, CPU가 실제 작업을 처리하는 것보다 스왑 작업에 더 많은 시간을 소비하는 현상입니다. 이로 인해 성능이 급격히 저하되며, 결국 CPU 사용률도 떨어지게 됩니다.
스레싱 발생 과정
1. 멀티 프로그래밍 정도 증가: 동시에 실행되는 프로세스의 수가 늘어나면 CPU 사용률을 높이려는 의도에서 물리 메모리에 더 많은 프로세스를 올리게 됩니다.
2. 메모리 부족: 메모리는 한정되어 있기 때문에 모든 프로세스의 모든 페이지를 물리 메모리에 적재할 수 없으며, 페이지 폴트가 빈번하게 발생합니다.
3. 페이지 폴트 증가: 페이지 폴트가 많아지면 프로세스가 필요로 하는 페이지를 계속 스왑 영역에서 불러와야 하며, 이에 따라 스왑 작업이 많아집니다.
4. CPU 사용률 감소: 페이지 폴트로 인한 스왑 작업이 지나치게 많아지면 CPU가 작업에 집중하지 못하고, 결국 CPU 사용률이 낮아집니다.
5. 스레싱: 스왑 작업이 CPU의 작업을 방해하게 되어 CPU 사용률이 0에 가까워지며, 시스템이 스왑 작업에 묶여 제대로 동작하지 않는 상태가 됩니다.
스레싱은 물리 메모리의 부족이 근본 원인으로, 이를 하드웨어적으로 해결하려면 물리 메모리의 크기를 늘리면 되지만, 단순히 메모리 크기를 늘린다고 해서 항상 성능이 크게 향상되는 것은 아닙니다.
워킹셋(Working Set)
워킹셋은 각 프로세스가 실행되기 위해 필요한 페이지들의 집합을 의미합니다. 프로세스는 지역성 이론에 따라 특정 시간 동안 주로 사용하는 데이터나 코드를 메모리에 올려두는데, 이 페이지들의 집합을 워킹셋이라고 합니다. 워킹셋을 정의하는 것은 스레싱을 방지하고 시스템 성능을 최적화하는 중요한 방법 중 하나입니다.
- 지역성 이론: 프로세스는 특정 시점에서 일정한 범위의 메모리 공간을 집중적으로 참조하는 경향이 있습니다. 이 지역성을 고려해, 자주 사용하는 페이지들만 메모리에 올려두는 것이 효율적입니다.
스레싱 방지 방법: 워킹셋 모델
운영체제는 각 프로세스가 어느 정도의 페이지를 필요로 하는지 모니터링하여, 워킹셋 모델을 통해 적절한 페이지 수를 유지합니다. 다음과 같은 과정을 통해 스레싱을 방지할 수 있습니다.
1. 페이지 할당 및 조정:
- 프로세스가 실행되면 처음에 일정량의 페이지를 할당합니다.
- 페이지 폴트가 발생하면 해당 프로세스에 더 많은 페이지를 할당해 메모리 사용량을 늘립니다.
- 반대로 페이지 폴트가 거의 발생하지 않으면 페이지가 과도하게 할당된 것으로 간주하고, 메모리 낭비를 방지하기 위해 일부 페이지를 회수합니다.
2. 워킹셋 유지:
- 현재 메모리에 적재된 페이지들이 프로세스의 워킹셋에 속한다고 가정하고, 이 페이지들을 유지합니다.
- 페이지 폴트가 많이 발생하면 워킹셋에 필요한 페이지를 추가하고, 사용 빈도가 낮은 페이지를 스왑 영역으로 내보냅니다.
스레싱은 프로세스와 메모리 간의 균형이 깨질 때 발생하며, 이를 방지하기 위해서는 프로세스마다 적절한 양의 페이지를 메모리에 적재하고, 워킹셋을 기반으로 효율적으로 관리해야 합니다. CPU 사용률을 높이기 위한 멀티 프로그래밍의 정도는 물리 메모리의 용량과 페이지 교체 정책에 의해 결정되며, 운영체제는 이를 지속적으로 모니터링하여 스레싱을 방지할 수 있습니다.
입출력 장치
주변장치
주변장치의 기본 구성
I/O 디바이스는 CPU와 메모리 외부에 있는 장치들로, 그래픽카드, 하드디스크, SSD, 키보드, 마우스 등 여러 가지가 포함됩니다.
이들은 메인보드에 버스를 통해 연결되며, 각각의 장치 상태와 데이터를 보관할 수 있는 레지스터들을 가집니다.
장치마다 데이터를 전송하는 방식이 다르며, 캐릭터 디바이스와 블록 디바이스로 나뉩니다.
캐릭터 디바이스: 마우스, 키보드 등 적은 양의 데이터를 전송하는 장치.
블록 디바이스: 하드디스크, SSD 등 많은 양의 데이터를 전송하는 장치.
입출력 제어기와 버스
초기에는 CPU가 직접 주변장치에서 데이터를 가져오면서 입출력 작업을 처리했으나, 이는 효율성이 떨어졌습니다. 이를 해결하기 위해 입출력 제어기(I/O Controller)가 도입되어 CPU가 다른 작업을 할 수 있도록 입출력 제어기가 입출력 작업을 관리하게 되었습니다.
입출력 제어기는 CPU와 빠른 메모리를 연결하는 시스템 버스와, 주변장치들을 연결하는 입출력 버스로 구성됩니다.
속도 차이를 해결하기 위해, 입출력 버스는 고속 입출력 버스와 저속 입출력 버스로 나뉩니다. 예를 들어, 그래픽 카드와 같은 고속 장치는 시스템 버스에 바로 연결되기도 합니다.
DMA(Direct Memory Access) 제어기가 도입되어 CPU의 개입 없이도 입출력 제어기가 메모리에 직접 데이터를 읽고 쓸 수 있게 되었으며, 이를 Memory Mapped I/O라고 부릅니다.
마우스, 키보드
마우스
광학 마우스는 카메라로 마우스 아래의 이미지를 초당 수천 회 촬영해 마우스의 움직임을 감지합니다.
마우스의 디바이스 컨트롤러는 이 데이터를 분석하고 인터럽트를 통해 CPU에 알립니다. CPU는 운영체제와 애플리케이션이 마우스 이벤트를 처리할 수 있게 해줍니다.
키보드
키보드도 마우스와 비슷한 방식으로 동작하며, 사용자가 입력한 키를 디바이스 컨트롤러가 감지해 CPU로 인터럽트를 보냅니다. 운영체제는 해당 이벤트를 적절한 애플리케이션에 전달합니다.
하드디스크, SSD
하드디스크
하드디스크는 물리적으로 회전하는 플래터(Platter)와 이를 읽는 헤드(Head)로 구성됩니다.
실린더(Cylinder)는 여러 개의 트랙이 있는 위치를 의미하며, 섹터(Sector)는 하드디스크의 가장 작은 저장 단위입니다.
하드디스크의 성능은 데이터를 읽기 위해 헤드를 움직이는 시간이 느려지는 탐색 시간(Seek Time)에 의해 제한됩니다. 이 시간 때문에 하드디스크는 상대적으로 느리게 동작합니다.
SSD(Flash Memory)
SSD는 전기적으로 데이터를 읽고 쓰기 때문에 빠르고 조용하며, 하드디스크와 달리 기계적 움직임이 없어서 충격에 강합니다.
다만, 플래시 메모리는 같은 지점에 데이터를 여러 번 쓰고 지우는 작업에 한계가 있어, 반복적인 쓰기 작업이 장치의 수명을 단축시킬 수 있습니다.
파일 시스템
파일과 시스템
파일 시스템은 데이터 저장 및 관리를 위해 설계된 소프트웨어 구성 요소로, 파일과 디렉토리의 생성, 수정, 삭제를 포함한 다양한 작업을 처리합니다.
파일 시스템의 구조와 역할
파일 시스템은 파일 및 디렉토리를 관리하며, 디스크와 같은 저장 장치에 데이터를 효율적으로 저장합니다. 주요 기능은 다음과 같습니다:
파일 및 디렉토리 생성, 수정, 삭제
파일 접근 권한 관리
데이터 무결성 보장
백업 및 복구, 암호화
파일 구조
파일은 다양한 데이터 집합으로 이루어지며, 그 구성 방식에 따라 세 가지 주요 구조로 구분됩니다:
순차 파일 구조: 데이터가 연속적으로 저장되는 구조로, 파일의 특정 지점에 접근하는 데 시간이 오래 걸리지만 구조가 단순하여 공간 낭비가 적습니다.
직접 파일 구조: 해시 함수를 이용해 데이터를 저장하는 방식으로, 데이터 접근이 빠르지만, 해시 함수의 선택이 중요합니다.
인덱스 파일 구조: 순차 접근과 직접 접근의 장점을 결합한 방식으로, 인덱스 테이블을 이용해 빠르게 데이터를 검색할 수 있습니다.
디렉토리
디렉토리 역시 파일의 한 종류로, 다른 파일들의 정보를 저장하는 역할을 합니다. 다단계 디렉토리 구조를 통해 트리 형태로 파일을 관리할 수 있으며, 윈도우의 바로가기처럼 순환 구조를 가지기도 합니다.
파일과 디스크
파일이 저장될 때, 디스크는 일정 크기로 나뉜 블록으로 데이터를 저장합니다. 블록 할당 방식은 크게 두 가지로 구분됩니다:
연속 할당: 파일의 블록이 연속적으로 저장되는 방식으로, 외부 단편화 문제가 발생할 수 있어 현대 시스템에서는 잘 사용하지 않습니다.
불연속 할당: 파일의 블록들이 분산되어 저장되며, 연결 할당과 인덱스 할당 방식이 존재합니다.
연결 할당: 연결 리스트 구조로 파일 블록을 관리하는 방식입니다.
인덱스 할당: 인덱스 블록을 통해 여러 데이터 블록에 접근하는 방식입니다. 유닉스와 리눅스에서는 이를 i-node로 관리합니다.
디스크 관리 및 블록 크기
블록 크기가 작으면 내부 단편화가 줄어들어 공간 낭비가 적어지지만, 관리할 블록 수가 많아집니다. 반대로, 블록 크기가 크면 내부 단편화로 인해 공간 낭비가 발생할 수 있지만, 관리할 블록 수는 줄어듭니다.
파일 삭제 및 복구
파일을 삭제할 때, 실제로 파일의 데이터가 사라지지 않고 파일 시스템은 파일 테이블에서 파일의 헤더만 삭제하고, 사용했던 블록을 프리 블록 리스트에 추가합니다. 이런 이유로 데이터 복구 프로그램을 통해 삭제된 파일의 데이터를 복원할 수 있습니다.