>시스템 튜토리얼 >리눅스 >Linux 커널에 대한 심층적인 이해: 가상 주소 공간과 물리적 메모리 간의 매핑 관계

Linux 커널에 대한 심층적인 이해: 가상 주소 공간과 물리적 메모리 간의 매핑 관계

WBOY
WBOY원래의
2024-06-03 09:28:441104검색

비디오 메모리 매핑

화학 메모리를 총칭하여 주소 지정 가능 및 동적 랜덤 액세스 메모리(DRAM)라고 합니다. 커널만이 수학 메모리에 직접 접근할 수 있습니다.

Linux 커널은 각 프로세스에 독립적인 가상 주소 공간을 제공하지만 이 주소 공간은 연속적입니다. 이러한 방식으로 프로세스는 비디오 메모리, 더 정확하게는 가상 비디오 메모리에 쉽게 액세스할 수 있습니다. 가상 주소 공간의 내부는 커널 공간과 사용자 공간의 두 부분으로 나뉩니다.

linux 用户分配空间_linux磁盘分配空间_linux分配用户权限

프로세스가 사용자 모드에 있으면 사용자 공간 메모리에만 액세스할 수 있습니다. 커널 모드에 들어간 후에만 커널 공간 메모리에 액세스할 수 있습니다. 실제로 각 프로세스의 주소 공간에는 커널 공간이 포함되지만 이 커널 공간은 동일한 화학적 메모리, 즉 공유 동적 링크 라이브러리, 공유 그래픽 메모리 등과 연관되어 있습니다. 프로세스가 커널 상태로 전환되면 커널 공간 메모리에 쉽게 액세스할 수 있습니다.

모든 가상 메모리가 케미컬 메모리로 할당되는 것은 아니며, 실제로 사용되는 가상 메모리만 케미컬 메모리로 할당됩니다. 그러나 할당된 케미컬 메모리는 메모리 매핑을 통해 관리됩니다. 비디오 메모리 매핑은 가상 비디오 메모리 주소를 화학적 비디오 메모리 주소로 매핑하는 것입니다. 비디오 메모리 매핑을 완료하기 위해 커널은 각 프로세스의 페이지 테이블을 유지하여 가상 주소와 화학적 주소 간의 매핑 관계를 기록합니다.

linux磁盘分配空间_linux分配用户权限_linux 用户分配空间

페이지 테이블은 실제로 CPU의 비디오 메모리 관리 장치 MMU에 저장됩니다. 이러한 방식으로 정상적인 상황에서는 프로세서가 하드웨어를 통해 액세스할 비디오 메모리를 직접 찾을 수 있습니다. 프로세스가 액세스한 가상 주소를 페이지 테이블에서 찾을 수 없으면 시스템은 페이지 오류 예외를 형성하고 커널 공간에 들어가 화학적 메모리를 할당하고 프로세스 페이지 테이블을 업데이트한 다음 마지막으로 사용자 공간으로 돌아가서 작업을 재개합니다. 프로세스의 작동.

CPU 컨텍스트 스위칭의 TLB(TranslationLookasideBuffer, Translation Lookaside Buffer)는 MMU의 페이지 테이블 캐시입니다. 프로세스의 가상 주소 공간은 Linux 시스템과 독립적이고 TLB 액세스 속도가 MMU보다 훨씬 빠르기 때문에 프로세스의 컨텍스트 전환과 TLB 새로 고침 횟수를 줄임으로써 TLB 캐시 사용량을 높일 수 있습니다. 이를 통해 CPU의 메모리 액세스 성능이 향상됩니다.

MMU는 일반적으로 크기가 4KB인 페이지인 비디오 메모리 매핑의 가장 작은 단위를 지정합니다. 이러한 방식으로 각 비디오 메모리 매핑은 4KB의 비디오 메모리 공간 또는 4KB의 정수배와 연결되어야 합니다.

4KB 페이지는 전체 페이지 테이블을 매우 크게 만듭니다. 예를 들어 4GB/4KB = 32비트 시스템에서 페이지 테이블 항목이 1백만 개가 넘습니다. 너무 많은 페이지 테이블 항목 문제를 해결하기 위해 Linux는 다중 레벨 페이지 테이블과 거대한 페이지(HugePage)라는 두 가지 메커니즘을 제공합니다.

linux分配用户权限_linux 用户分配空间_linux磁盘分配空间

다단계 페이지 테이블은 비디오 메모리를 블록으로 나누어 관리하고, 원래의 매핑 관계를 블록 인덱스와 블록 내 스큐로 변경하는 것입니다. 일반적으로 가상 비디오 메모리 공간 중 아주 작은 부분만 사용되기 때문에 다중 레벨 페이지 테이블은 사용 중인 블록만 저장하므로 페이지 테이블 항목 수를 크게 줄일 수 있습니다. Linux는 4단계 페이지 테이블을 사용하여 비디오 메모리 페이지를 관리합니다. 처음 4개 항목은 페이지를 선택하는 데 사용되며 마지막 인덱스는 페이지 내의 왜곡을 나타냅니다.

linux 用户分配空间_linux磁盘分配空间_linux分配用户权限

대형 페이지는 일반 페이지보다 더 큰 비디오 메모리 블록입니다. 대용량 페이지는 일반적으로 Oracle, DPDK 등 많은 양의 비디오 메모리를 사용하는 프로세스에 사용됩니다.

이 메커니즘을 통해 페이지 테이블 매핑에서 프로세스는 가상 주소를 통해 수학 메모리에 액세스할 수 있습니다.

가상 비디오 메모리 공간 분배

상단은 커널 공간이고, 하단은 사용자 공간 메모리이며, 사용자 공간은 여러 개의 서로 다른 세그먼트로 나뉩니다

linux磁盘分配空间_linux分配用户权限_linux 用户分配空间

사용자 공간 비디오 메모리에는 낮은 수준부터 높은 수준까지 5가지 비디오 메모리 세그먼트가 있습니다

1. 코드 및 상수 등을 포함한 읽기 전용 섹션

linux磁盘分配空间_linux 用户分配空间_linux分配用户权限

2. 파노라마 변수 등을 포함한 데이터 세그먼트

3. 동적으로 할당된 비디오 메모리를 포함한 힙은 낮은 주소부터 시작하여 아래쪽으로 감소합니다

4. 동적 라이브러리, 공유 비디오 메모리 등을 포함한 파일 매핑 세그먼트는 높은 주소에서 시작하여 위쪽으로 감소합니다

5. 지역 변수 및 함수 호출 컨텍스트 등을 포함한 스택. 스택 크기는 일반적으로 8M로 고정되어 있습니다.

이 5개의 비디오 메모리 세그먼트 중에서 힙 및 파일 매핑된 비디오 메모리가 동적으로 할당됩니다. 예를 들어 C 표준 라이브러리의 malloc 또는 mmap()을 사용하면 힙 및 파일 매핑된 세그먼트에 각각 비디오 메모리를 동적으로 할당할 수 있습니다. 64비트 시스템의 비디오 메모리 분포는 비슷하지만 비디오 메모리 공간은 훨씬 더 큽니다

비디오 메모리 할당 및 재활용

malloc()은 C 표준 라이브러리에서 제공하는 비디오 메모리 할당 함수로, 시스템 호출에 대응하여 brk()와 mmap()이라는 두 가지 구현 방법이 있습니다.

linux磁盘分配空间_linux 用户分配空间_linux分配用户权限

작은 비디오 메모리 블록(128K보다 큼)의 경우 C 표준 라이브러리는 brk()를 사용하여 할당합니다. 즉, 비디오 메모리는 힙의 최상위 위치를 연결하여 할당됩니다. 이러한 종류의 비디오 메모리는 출시 직후 시스템에 반환되지 않고 재사용이 가능하도록 캐시됩니다.

linux磁盘分配空间_linux分配用户权限_linux 用户分配空间

큰 비디오 메모리 블록(128K 미만)의 경우 비디오 메모리 매핑 mmap()을 직접 사용하여 할당합니다. 즉, 파일 매핑 섹션에서 사용 가능한 비디오 메모리 조각을 찾아서 할당합니다.

이 두 가지 방법의 유사점과 차이점은 다음과 같습니다.

brk() 메서드의 캐싱은 페이지 오류 예외 발생을 줄이고 비디오 메모리 액세스 효율성을 향상시킬 수 있습니다. 그러나 이러한 종류의 비디오 메모리는 시스템에 반환되지 않기 때문에 비디오 메모리를 자주 할당하고 해제하면 비디오 메모리가 사용 중일 때 비디오 메모리 조각화가 발생합니다.

mmap() 메서드로 할당된 비디오 메모리는 해제 시 시스템에 직접 반환되므로 mmap이 발생할 때마다 페이지 폴트 예외가 발생합니다. 비디오 메모리가 사용량이 많은 경우 비디오 메모리 할당을 자주 수행하면 페이지 오류 예외가 많이 발생하여 커널의 관리 부담이 줄어듭니다. 이는 malloc이 큰 비디오 메모리 블록에만 mmap을 사용하는 이유이기도 합니다.

이 두 호출이 발생하면 실제로 비디오 메모리가 할당되지는 않지만 주의해야 합니다. 이런 종류의 비디오 메모리는 처음 액세스할 때만 할당됩니다. 즉, 페이지 폴트 예외를 통해 커널에 들어간 다음 커널이 비디오 메모리를 할당합니다.

일반적으로 Linux는 버디 시스템을 사용하여 비디오 메모리 할당을 관리합니다. 위에서 언급했듯이 이러한 종류의 그래픽은 MMU에서 페이지 단위로 관리됩니다. 파트너 시스템도 페이지 단위로 그래픽 메모리를 관리하며 인접한 페이지를 병합하여 그래픽 메모리 조각화를 줄입니다. brk 방법으로 인한 비디오 메모리 조각화).

실제 시스템 운영에서는 1K 미만 등 한 페이지보다 작은 개체가 많이 존재하게 되는데, 여기에 별도의 페이지를 할당하게 되면 비디오 메모리를 어떻게 할당해야 할까요?

사용자 공간 linux 사용자 할당 공간에서 brk()를 통해 malloc으로 할당한 비디오 메모리는 해제 시 즉시 시스템에 반환되지 않고 캐시되어 다시 사용됩니다.

커널 공간에서 Linux는 슬랩 할당자를 통해 작은 비디오 메모리를 관리합니다. slab은 파트너 시스템에 구축된 캐시로 생각할 수 있습니다. 주요 기능은 커널에 작은 개체를 할당하고 해제하는 것입니다.

linux 用户分配空间_linux磁盘分配空间_linux分配用户权限

비디오 메모리 재활용: 비디오 메모리의 경우 해제하지 않고 할당만 하면 비디오 메모리 누수가 발생하고 심지어 시스템 비디오 메모리를 모두 소모하게 됩니다. 따라서 응용 프로그램이 비디오 메모리를 모두 사용한 후에도 free() 또는 unmap()을 호출하여 사용되지 않은 비디오 메모리를 해제해야 합니다. 실제로 시스템은 프로세스가 모든 비디오 메모리를 사용하도록 허용하지 않습니다. 비디오 메모리가 부족한 것으로 확인되면 시스템은 다음 세 가지 형식과 같은 일련의 메커니즘을 사용하여 비디오 메모리를 회수합니다.

(1) 캐시를 재활용합니다. 예를 들어 LRU(LeastRecentlyUsed) 알고리즘을 사용하여 최근에 가장 적게 사용된 비디오 메모리 페이지를 재활용합니다.

(2) 자주 액세스하지 않는 비디오 메모리를 재활용하고 자주 사용하지 않는 비디오 메모리는 스왑 파티션(Swap)을 통해 C 드라이브로 직접 전송합니다. Swap은 C 드라이브 공간을 비디오 메모리로 사용합니다. 프로세스에서 일시적으로 사용하지 않는 데이터를 c 드라이브에 저장할 수 있습니다(이 프로세스를 스왑 아웃이라고 함). 프로세스가 해당 비디오 메모리에 액세스하면 이 데이터를 c 드라이브에서 비디오 메모리로 읽을 수 있습니다. 교환이라고 함). 스왑은 시스템의 사용 가능한 비디오 메모리를 늘리지만 일반적으로 비디오 메모리가 부족한 경우에만 스왑이 발생하며 C 드라이브의 읽기 및 쓰기 속도가 비디오 메모리보다 훨씬 느리기 때문에 스왑은 비디오 메모리 성능에 심각한 영향을 미칩니다. 문제.

(3) 프로세스 종료. 비디오 메모리가 부족하면 시스템은 OOM(OutofMemory, 커널 보호 메커니즘)을 통해 많은 양의 비디오 메모리를 차지하는 프로세스를 직접 종료합니다. OOM은 프로세스의 메모리 사용량을 모니터링하지만 oom_score를 사용하여 각 프로세스의 메모리 사용량에 점수를 매깁니다.

프로세스에서 소비하는 그래픽 메모리가 많을수록 oom_score가 높아집니다.

프로세스가 CPU를 많이 차지할수록 oom_score는 작아집니다.

이런 방식으로 프로세스의 oom_score가 클수록 더 많은 비디오 메모리가 소모되고 OOM에 의해 종료되기 쉬워 시스템을 더 잘 보호할 수 있습니다.

실제로 실제 작업 요구에 따라 관리자는 /proc 파일 시스템을 통해 프로세스의 oom_adj를 자동으로 설정하여 프로세스의 oom_score를 조정할 수 있습니다. oom_adj의 범위는 [-17,15]입니다. 값이 클수록 OOM에 의해 프로세스가 종료되기 쉽습니다. 값이 작을수록 OOM에 의해 프로세스가 종료될 가능성이 줄어듭니다. 엄격히 금지됩니다. 다음 명령을 사용하면 sshd 프로세스의 oom_adj를 -16으로 줄여 OOM에 의해 sshd 프로세스가 쉽게 종료되지 않도록 할 수 있습니다.

echo-16>/proc/$(pidofsshd)/oom_adj

linux磁盘分配空间_linux 用户分配空间_linux分配用户权限

linux磁盘分配空间_linux 用户分配空间_linux分配用户权限

버퍼 및 캐시

free 명령의 버퍼와 캐시는 모두 캐시를 의미하지만 용도가 다릅니다

1. 버퍼는 커널 버퍼에서 사용하는 비디오 메모리로 /proc/meminfo

의 버퍼 값에 해당합니다.

2. 캐시는 커널 페이지 캐시와 Slab에서 사용하는 비디오 메모리입니다. /proc/meminfo

에 있는 Cache와 SReclaimable의 합에 해당합니다.

간단히 말하면 Buffer는 C 드라이브 데이터의 캐시이고 Cache는 파일 데이터의 캐시입니다. 읽기 요청과 쓰기 요청 모두에 사용됩니다.

캐시(cache)는 우리가 흔히 볼 수 있는 1차 캐시, 2차 캐시, 3차 캐시 등 CPU와 비디오 메모리 사이의 데이터 교환률을 높이기 위해 CPU 관점에서 설계됐다. 프로그램을 실행하기 위해 CPU가 사용하는 명령과 데이터는 모두 비디오 메모리를 대상으로 합니다. 즉, 비디오 메모리에서 얻습니다. 비디오 메모리의 읽기 및 쓰기 속도가 느리기 때문에 CPU와 비디오 메모리 간의 데이터 교환 속도를 높이기 위해 CPU와 비디오 메모리 간의 캐시 속도가 비디오 메모리보다 빠릅니다. Linux 사용자는 공간을 할당하고 비용이 높으며 CPU에는 너무 많은 집적 회로를 통합할 수 없기 때문에 일반적으로 캐시가 상대적으로 작습니다. 나중에 속도를 더욱 향상시키기 위해 Intel 및 기타 회사에서는 수준을 줄였습니다. 2 캐시와 심지어 레벨 5 캐시도 CPU 실행인 프로그램의 지역성 원칙에 따라 설계되었습니다. 명령과 액세스된 데이터는 종종 특정 블록에 집중되므로 이 콘텐츠 블록을 로드한 후입니다. 캐시에 추가하면 CPU가 비디오 메모리에 액세스할 필요가 없으므로 액세스 속도가 향상됩니다. 실제로 캐시에 CPU에 필요한 콘텐츠가 없는 경우에도 비디오 메모리에 액세스해야 합니다.

비디오 메모리 읽기 및 C 디스크 읽기의 관점에서 캐시는 더 높은 읽기 효율성을 달성하기 위해 다시 액세스할 수 있는 데이터를 캐시하기 위해 더 많은 비디오 메모리를 사용하는 운영 체제로 이해될 수 있습니다.

버퍼는 비디오 메모리와 하드 디스크(또는 기타 I/O 장치) 간의 데이터 교환 속도를 높이도록 설계되었습니다. 분산된 쓰기 작업을 중앙 집중화하여 C 드라이브 조각화 및 반복적인 하드 디스크 탐색을 줄여 시스템 성능을 향상시킵니다. Linux에는 정기적으로 버퍼 내용을 지우는(즉, c 드라이브에 쓰기) 데몬 프로세스가 있으며, sync 명령을 통해 버퍼를 자동으로 지울 수도 있습니다.

간단히 말하면, 버퍼는 C 드라이브에 쓰려고 하고, 캐시는 C 드라이브에서 읽습니다. 버퍼는 다양한 프로세스에 의해 할당되며 입력 큐와 같은 측면에서 사용됩니다. 간단한 반례는 프로세스를 읽으려면 여러 배열이 필요하다는 것입니다. 모든 배열을 완전히 읽기 전에 프로세스는 원래 읽은 배열을 버퍼에 배치하고 저장합니다.

캐시는 C 드라이브의 I/O 요청에 자주 사용됩니다. 여러 프로세스가 특정 파일에 액세스하려는 경우 마지막 액세스를 용이하게 하기 위해 파일이 캐시되므로 시스템 성능이 향상될 수 있습니다.

위 내용은 Linux 커널에 대한 심층적인 이해: 가상 주소 공간과 물리적 메모리 간의 매핑 관계의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.