오늘은 Linux
의 메모리 관리에 대해 공부하겠습니다.
CURD
에 능숙한 경영학과 학생들에게 메모리 관리는 우리와는 거리가 멀게 느껴집니다. 하지만 이 지식 포인트는 대중적이지는 않지만(많은 사람들이 배우고 나면 전혀 사용하지 않을 것으로 추정됨), 확실히 기초의 기초입니다.
이것은 무술 소설에 나오는 내면의 근력 단련과 같습니다. 배우고 나면 당장 결과가 나오지는 않지만, 키가 더 커질 것이기 때문에 앞으로의 발전에 큰 도움이 될 것입니다.
기사에 나오는 예시 사진은 모두 제가 그린 것입니다. 그림을 그리는 것보다 코딩하는 것보다 시간이 더 걸리지만, 글보다 그림을 보면 다들 직관적으로 이해하기 때문에 계속 그림을 그립니다. 고화질 샘플 사진이 필요한 학생들을 위해 기사 마지막 부분에 사진을 얻을 수 있는 방법이 있습니다.
좀 더 실용적으로 말하자면, 면접에서 자신이 이러한 지식을 알고 있다는 사실을 무심코 드러내고 자세히 말할 수 있다면 면접관이 당신에게 더 관심을 갖게 될 수도 있고 승진, 연봉 인상, 취업을 할 수도 있습니다. 인생의 정점이 한걸음 더 다가왔습니다.
전제 합의: 이 문서에서 논의된 기술 내용의 전제는 운영 체제 환경이 x86
32비트 x86
架构的 32 位 Linux
시스템.
최신 운영 체제에서도 메모리는 여전히 컴퓨터에서 매우 귀중한 리소스입니다. 컴퓨터에 몇 테라바이트의 솔리드 스테이트 드라이브가 있는지 살펴보고 메모리 크기도 살펴보세요.
시스템 메모리 자원을 최대한 활용하고 관리하기 위해 Linux는 가상 메모리 관리 기술을 사용합니다. 가상 메모리 기술을 사용하여 각 프로세스는 서로 간섭하지 않는 4GB 가상 주소 공간을 갖습니다.
프로세스 초기화 할당 및 작업은 이 "가상 주소"를 기반으로 합니다. 프로세스가 실제로 메모리 자원에 액세스해야 하는 경우에만 가상 주소와 물리적 주소 간의 매핑이 설정되고 물리적 메모리 페이지가 전송됩니다.
부적절한 비유를 하자면, 사실 이 원리는 현재의 XX 네트워크 디스크와 동일합니다. 네트워크 디스크 공간이 1TB라면 정말 이렇게 큰 공간이 단번에 주어질 수 있다고 생각하시나요? 아직 너무 어리잖아요. 물건을 넣어야 공간이 할당됩니다. 실제 넣은 만큼의 공간이 할당됩니다. 하지만 귀하와 귀하의 친구 모두에게 1TB의 공간이 있는 것 같습니다.
4GB 프로세스 가상 주소 공간은 "사용자 공간"과 "커널 공간"의 두 부분으로 나뉩니다.
사용자 공간 커널 공간
위 장에서 우리는 이미 사용자 공간이든 커널 공간이든 사용되는 주소가 가상 주소라는 것을 알고 있습니다. 프로세스가 실제로 메모리에 액세스해야 할 때 커널의 "요청"에 의해 "페이지 오류 예외"가 생성됩니다. 페이징 메커니즘"을 물리적 주소로 전송합니다. 메모리 페이지.
가상 주소를 메모리의 물리적 주소로 변환합니다. 여기에는 MMU
메모리 관리 장치를 사용하여 가상 주소(세그먼트 페이지 유형) 주소 변환을 분할하고 페이징하는 과정이 포함됩니다. 자세한 내용은 컴퓨터 구성 원리 교과서를 참조하세요.
세그먼트 페이지 메모리 관리 주소 변환
Linux
커널은 물리적 메모리를 다음과 같은 3가지 관리 영역으로 나눕니다.
DMA
内存区域。包含0MB~16MB之间的内存页框,可以由老式基于ISA
的设备通过DMA
사용되며 커널의 주소 공간에 직접 매핑됩니다.
일반 메모리 영역. 커널의 주소 공간에 직접 매핑되는 16MB~896MB 사이의 메모리 페이지 프레임, 일반 페이지 프레임을 포함합니다.
고급 메모리 영역. 직접 매핑되지 않은 896MB 이상의 메모리 페이지 프레임을 포함합니다. 메모리 페이지 프레임의 이 부분은 영구 매핑과 임시 매핑을 통해 액세스할 수 있습니다.
물리적 메모리 영역 분할
사용자 프로세스가 접근할 수 있는 것은 "사용자 공간"입니다. 각 프로세스는 자신만의 독립적인 사용자 공간을 가지며, 가상 주소 범위는 0x00000000
至 0xBFFFFFFF
총 용량은 3G입니다.
사용자 프로세스는 일반적으로 사용자 공간의 가상 주소에만 액세스할 수 있으며 인라인 작업이나 시스템 호출을 실행할 때만 커널 공간에 액세스할 수 있습니다.
프로세스(실행된 프로그램)가 차지하는 사용자 공간은 "일관된 액세스 속성을 가진 주소 공간이 함께 저장된다"는 원칙에 따라 5
서로 다른 메모리 영역으로 구분됩니다. 액세스 속성은 "읽기 가능, 쓰기 가능, 실행 가능 등"을 참조합니다.
코드 조각
코드 세그먼트는 실행 파일의 동작 명령과 실행 프로그램의 이미지를 메모리에 저장하는 데 사용됩니다. 코드 세그먼트는 런타임 시 불법 수정으로부터 보호되어야 하므로 읽기 작업만 허용되고 쓰기는 불가능합니다.
데이터 세그먼트
데이터 세그먼트는 초기화된 전역 변수를 실행 파일에 저장하는 데 사용됩니다. 즉, 프로그램에서 정적으로 할당한 변수 및 전역 변수를 저장합니다.
BSS 섹션
BSS
段包含了程序中未初始化的全局变量,在内存中 bss
모든 세그먼트를 0으로 설정하세요.
힙 heap
힙은 프로세스가 실행되는 동안 동적으로 할당되는 메모리 세그먼트를 저장하는 데 사용되며 크기는 고정되지 않으며 동적으로 확장되거나 축소될 수 있습니다. 프로세스가 메모리를 할당하기 위해 malloc과 같은 함수를 호출하면 새로 할당된 메모리가 힙에 동적으로 추가됩니다(힙이 확장됨). free와 같은 함수를 사용하여 메모리를 해제하면 해제된 메모리가 힙에서 제거됩니다. (힙이 줄어듭니다).
stack
에서 선언한 변수는 포함되지 않으며, 정적이란 변수를 데이터 세그먼트에 저장하는 것을 의미합니다). 또한, 함수가 호출되면 해당 매개변수도 호출을 시작한 프로세스의 스택에 푸시되고, 호출이 완료된 후 함수의 반환 값도 스택에 다시 저장됩니다. 스택의 선입후출 기능으로 인해 스택은 통화 장면을 저장/복원하는 데 특히 편리합니다. 이런 의미에서 스택은 임시 데이터를 저장하고 교환하는 메모리 영역으로 생각할 수 있습니다. static
아키텍처에서는 스택이 아래쪽으로 확장되고 힙이 위쪽으로 확장되는데, 이는 서로 상대적입니다. BSS
段、堆通常是被连续存储在内存中,在位置上是连续的,而代码段和栈往往会被独立存放。堆和栈两个区域在 i386
명령을 사용하여 컴파일된 프로그램의 각 메모리 영역 크기를 확인할 수도 있습니다. size
으아악
용량에는 커널 공간에서 실행되는 커널 이미지, 물리적 페이지 테이블, 드라이버 등이 포함됩니다. x86 32
位系统里,Linux 内核地址空间是指虚拟地址从 0xC0000000
开始到 0xFFFFFFFF
为止的高端内存地址空间,总计 1G
의 커널 공간 주소 범위는 직접 메모리 매핑 영역입니다. Direct Memory Region
:从内核空间起始地址开始,最大896M
직접 매핑 영역의 896MB의 "선형 주소"가 "물리적 주소"의 앞부분에 직접 연결됩니다 896MB
进行映射,也就是说线性地址和分配的物理地址都是连续的。内核地址空间的线性地址0xC0000001
所对应的物理地址为0x00000001
,它们之间相差一个偏移量PAGE_OFFSET = 0xC0000000
이 영역에는 선형 주소와 물리 주소 사이에 선형 변환 관계가 있습니다. "선형 주소 = PAGE_OFFSET
+ 物理地址」也可以用 virt_to_phys()
커널 가상 공간의 선형 주소를 물리 주소로 변환하는 함수입니다.
커널 공간 선형 주소 범위는 896M부터 1G까지이며, 128MB 용량의 주소 범위는 고급 메모리 선형 주소 공간이라고 불리는 이유는 무엇입니까? 아래에서 설명해 드리겠습니다.
앞서 언급했듯이 커널 공간의 전체 크기는 1GB이며, 커널 공간의 시작 주소에서 시작하는 896MB의 선형 주소를 물리적 주소 크기 896MB의 주소 범위에 직접 매핑할 수 있습니다.
한발 물러서서 커널 공간의 1GB 선형 주소가 물리적 주소로 매핑되더라도 물리적 메모리 주소 범위 중 최대 1GB까지만 주소를 지정할 수 있습니다.
지금 가지고 있는 메모리스틱의 크기는 얼마나 되나요? 일어나세요, 이제 거의 2023년이 되었습니다. 대부분의 PC 메모리는 1GB보다 큽니다!
그래서 커널 공간은 마지막 128M 주소 범위를 꺼내어 다음과 같은 3개의 고급 메모리 매핑 영역으로 나누어 전체 물리적 주소 범위를 주소 지정했습니다. 사용 가능한 선형 주소 공간이 설치 가능한 메모리보다 훨씬 크기 때문에 64비트 시스템에서는 이 문제가 발생하지 않습니다.
vmalloc Region
该区域由内核函数vmalloc
来分配,特点是:线性空间连续,但是对应的物理地址空间不一定连续。vmalloc
할당된 선형 주소에 해당하는 물리적 페이지는 low-end 메모리에 있을 수도 있고 high-end 메모리에 있을 수도 있습니다.
Persistent Kernel Mapping Region
该区域可访问高端内存。访问方法是使用 alloc_page (_GFP_HIGHMEM)
分配高端内存页或者使用kmap
함수는 할당된 고급 메모리를 이 영역에 매핑합니다.
Fixing kernel Mapping Region
该区域和 4G 的顶端只有 4k 的隔离带,其每个地址项都服务于特定的用途,如 ACPI_BASE
등등.
커널 공간 물리적 메모리 매핑
위에서 이야기할 내용이 많으니 다음 섹션으로 넘어가지 마세요. 그 전에 위에서 말한 내용을 검토해 보겠습니다. 위의 장을 주의 깊게 읽으셨다면 여기에 또 다른 그림이 그려져 있으며 이제 여러분은 메모리 관리에 대한 전체적인 그림을 마음 속에 갖게 되실 것입니다.
커널 공간과 사용자 공간 전체 그림
커널이 시스템에서 가상 메모리를 관리하려면 메모리 관리 데이터 구조를 추상화해야 합니다. "할당, 해제 등"과 같은 메모리 관리 작업은 이러한 데이터 구조 작업을 기반으로 합니다. 가상 메모리 영역을 관리하는 구조입니다.
이전 장 "프로세스와 메모리"에서 Linux 프로세스는 5가지 메모리 영역, 즉 코드 세그먼트, 데이터 세그먼트, BSS
、堆、栈,内核管理这些区域的方式是,将这些内存区域抽象成vm_area_struct
메모리 관리 개체로 나눌 수 있다고 언급했습니다.
vm_area_struct
是描述进程地址空间的基本管理单元,一个进程往往需要多个vm_area_struct
来描述它的用户空间虚拟地址,需要使用「链表」和「红黑树」来组织各个vm_area_struct
.
연결된 목록은 모든 노드를 탐색해야 할 때 사용되는 반면, 레드-블랙 트리는 주소 공간에서 특정 메모리 영역을 찾는 데 적합합니다. 커널은 메모리 영역에서 다양한 작업에 대한 고성능을 달성하기 위해 두 가지 데이터 구조를 모두 사용합니다.
사용자 공간 프로세스의 주소 관리 모델:
wm_arem_struct
커널 공간 장에서 "동적 메모리 매핑 영역"에 대해 언급했습니다. 커널 함수에 의해 할당된 선형 주소에 해당하는 물리적 페이지vmalloc
来分配,特点是:线性空间连续,但是对应的物理地址空间不一定连续。vmalloc
는 저사양 메모리에 있을 수도 있고 고급 메모리에 있을 수도 있습니다.
vmalloc
分配的地址则限于vmalloc_start
与vmalloc_end
之间。每一块vmalloc
分配的内核虚拟内存都对应一个vm_struct
结构体,不同的内核空间虚拟地址之间有4k
크기 교차 방지 자유 영역 파티션.
사용자 공간의 가상 주소 특성과 유사하게 이러한 가상 주소는 물리적 메모리와 단순 매핑 관계를 갖지 않으며 커널 페이지 테이블을 통해 물리적 주소 또는 물리적 페이지로 변환되어야 하며 아직 매핑되지 않았을 수 있습니다. 페이지 부재가 발생할 때까지 매핑되지 않습니다. 실제로 물리적 페이지를 할당합니다.
동적 메모리 매핑
Linux
메모리 관리는 매우 복잡한 시스템입니다. 이 기사에서 설명하는 내용은 거시적 관점에서 메모리 관리의 전체 그림을 보여 주지만 일반적으로 채팅을 할 때는 이 지식만으로도 충분합니다. 물론 나는 또한 모두가 독서를 통해 더 깊은 원리를 이해할 수 있기를 바랍니다.
이 글은 특정 포인트를 깊이 있게 공부하고 싶을 때, 이 장들에서 진입점을 찾을 수 있고, 메모리 관리의 거시적 관점에서 이 지식 포인트의 위치를 찾아볼 수 있는 색인형 학습 가이드로 활용될 수 있습니다.
이 글을 작성하면서 지식 지표로 활용할 수 있는 예제 다이어그램도 많이 그렸습니다. 개인적으로는 글을 읽는 것보다 사진을 보는 것이 더 명확하다고 생각합니다. 내 공식 계정 "백엔드 기술 학교" 배경에 있는 "Management" 이 사진의 고해상도 원본입니다.
오래된 규칙입니다. 기사의 목적은 지식을 공유하는 것입니다. 기술적인 기사의 경우 기사에 명백한 오류가 있는 경우 최대한 정확성을 보장하기 위해 반복적으로 확인하겠습니다. 함께 토론을 통해 배워봅시다. 오늘의 기술 공유는 여기까지입니다. 다음 호에서 만나요.
위 내용은 Linux 메모리 관리를 이해하지 못한다고 말하지 마세요. 10장의 사진을 통해 이해하실 수 있습니다!의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!