이 기사는 Nginx 메모리 관리(그림)에 대한 심층적인 이해를 제공합니다. 필요한 친구가 참고할 수 있기를 바랍니다.
1. 개요
애플리케이션의 메모리는 간단히 힙 메모리와 스택 메모리로 나눌 수 있습니다. 스택 메모리의 경우 함수가 컴파일되면 컴파일러는 스택 공간의 자체 관리를 실현하기 위해 스택의 현재 포인터 위치를 이동하는 코드를 삽입합니다. 힙 메모리의 경우 일반적으로 프로그래머가 관리해야 합니다. 우리가 일반적으로 이야기하는 메모리 관리는 힙 공간 메모리 관리일 뿐입니다.
메모리의 경우 메모리 적용, 메모리 사용, 메모리 해제의 3단계로 사용을 단순화할 수 있습니다. 메모리를 적용하고 사용하려면 일반적으로 프로그래머의 명시적인 작업이 필요하지만 메모리를 해제하는 데 반드시 프로그래머의 명시적인 작업이 필요한 것은 아닙니다. 현재 많은 고급 언어에서는 가비지 수집 메커니즘을 제공하며 메모리를 해제할 시간을 선택할 수 있습니다. 예: Go와 Java는 가비지 수집을 구현했지만 C 언어에서는 아직 가비지 수집을 구현하지 않았습니다. C++에서는 스마트 포인터를 통해 가비지 수집을 수행할 수 있습니다.
언어 수준의 메모리 관리 외에도 때때로 프로그램에서 직접 메모리를 관리해야 하는 경우가 있습니다. 일반적으로 메모리 관리는 주로 다음과 같은 문제를 해결하는 것이라고 생각합니다.
어떻게? 사용자가 메모리를 신청할 때까지 사용자 요구에 맞는 메모리 블록을 빠르게 찾으십니까?
사용자가 메모리를 해제할 때 메모리 조각화를 방지하는 방법은 무엇입니까?
언어 수준에서 구현된 메모리 관리이든 응용 프로그램 자체에서 구현된 메모리 관리이든 대부분의 메모리는 크기에 따라 여러 유형으로 나뉘며 각각 다른 관리 모드를 사용합니다. 일반적인 분류는 연결된 목록을 통해 다양한 유형의 메모리를 2의 정수 거듭제곱으로 나누는 것입니다. 쿼리할 때 해당 크기의 연결된 목록에서 검색하면 더 큰 메모리 블록에서 조각을 가져오는 것을 고려할 수 있습니다. 그것을 여러 개의 작은 기억 지점으로 나누는 것입니다. 물론 특히 큰 메모리의 경우 언어 수준 메모리 관리에서 메모리 관리 관련 시스템 호출을 직접 호출할 수 있고, 애플리케이션 수준 메모리 관리에서 언어 수준 메모리 관리를 직접 사용할 수 있습니다.
nginx 메모리 관리는 전체적으로 두 부분으로 나눌 수 있습니다.
첫 번째 부분은 프로세스에 일반적으로 필요한 메모리 관리에 사용되는 일반 메모리 풀입니다.
두 번째 부분은 다음과 같습니다. 공유 메모리 관리입니다. 전반적으로 공유 메모리는 메모리 풀보다 훨씬 복잡합니다.
2.nginx 메모리 풀 관리
2.1 설명
이 부분에서 사용된 nginx 버전은 1.15.3
구체적인 소스코드는 src/core/를 참고하세요. ngx_palloc.c 파일
2.2 nginx 구현
2.2.1 사용 프로세스
nginx 메모리 풀 사용은 비교적 간단하며 3단계로 나눌 수 있습니다.
ngx_create_pool 함수를 호출하여 가져옵니다. ngx_pool_t 포인터.
//size代表ngx_pool_t一块的大小 ngx_pool_t* ngx_create_pool(size_t size, ngx_log_t *log)n Ngx_palloc을 호출하여 메모리를 신청하고 메모리를 해제합니다(큰 메모리 조각을 해제하거나 전체 메모리 풀을 해제할 수 있음)
R
//从pool中申请size大小的内存 void* ngx_palloc(ngx_pool_t *pool, size_t size)E2.2.2 구체적인 구현
//释放从pool中申请的大块内存 ngx_int_t ngx_pfree(ngx_pool_t *pool, void *p) //释放整个内存池 void ngx_destroy_pool(ngx_pool_t *pool)
소형 메모리는 해제되지 않습니다. 나중에 더 이상 사용하지 않더라도 메모리를 해제할 필요가 없습니다. 사용자는 자신이 사용하는 메모리 블록이 큰지 작은지 알 수 없는 경우가 있으므로 ngx_pfree 함수를 호출하여 공간을 해제할 수도 있습니다. 이 함수는 큰 공간 연결 리스트에서 메모리를 검색하여 발견되면 메모리를 해제합니다. . 작은 메모리의 경우 처리가 수행되지 않습니다.
큰 메모리 블록의 경우 nginx는 이러한 메모리를 연결된 목록에 저장하고 풀->대형을 통해 관리합니다. 사용자 관리형 대용량 메모리를 위한 ngx_pool_large_t 구조는 이 메모리 풀의 작은 메모리 블록에서 적용된다는 점은 주목할 가치가 있습니다. 이는 nginx가 ngx_pool_large_t 구조를 직접 재사용할 수 없음을 의미합니다. 사용자가 큰 메모리 공간을 신청해야 하는 경우 c 함수 라이브러리 malloc을 사용하여 공간을 신청한 후 특정 ngx_pool_large_t 구조에 마운트합니다. nginx에 새로운 ngx_pool_large_t 구조가 필요한 경우 먼저 pool->large 연결 목록의 처음 세 요소를 확인하여 사용 가능한 요소가 있는지 확인합니다. 그렇지 않으면 새 ngx_pool_large_t를 생성합니다. 구조.
3.nginx 공유 메모리 관리
3.1 설명
이 부분에 사용된 nginx 버전은 1.15.3
이 부분의 소스 코드에 대한 자세한 내용은 src/core를 참조하세요. /ngx_slab.c, src/core /ngx_shmtx.c
nginx 공유 메모리 콘텐츠는 상대적으로 크므로 이 문서에서는 간략한 개요만 제공합니다.
3.2 공유 메모리 직접 사용
3.2.1 기본
nginx는 나중에 여러 프로세스를 동기화하기 위해 뮤텍스 잠금을 생성해야 합니다. 또한 nginx에는 설정(stat_stub)과 같은 일부 통계 정보가 필요할 수 있습니다. 이러한 변수를 특별히 관리할 필요는 없으며 공유 공간을 열어서 직접 사용하면 됩니다.
stat_stub 설정 후 필요한 통계 정보도 공유 메모리에 저장됩니다. 여기서는 설명을 위해 nginx의 뮤텍스 잠금만 사용합니다.
3.2.2 nginx mutex lock 구현
nginx mutex lock에는 두 가지 솔루션이 있습니다. 시스템이 원자 연산을 지원하는 경우 원자 연산이 사용되고 지원되지 않는 경우 파일 잠금이 사용됩니다. 이 섹션의 소스 코드는 ngx_event_module_init 함수를 참조하세요.
아래 그림은 상호 배제 잠금을 구현한 파일 잠금의 개략도입니다.
다음 그림은 뮤텍스 잠금을 구현하기 위한 원자 연산의 개략도입니다.
Problem
새로 시작된 마스터가 이전 마스터에 신호를 보낸 후 이전 마스터가 구성을 다시 로드하고(ngx_init_cycle 함수) 새 작업자 프로세스를 생성합니다. 작업자 프로세스는 이전 작업자 프로세스와 동일한 잠금을 사용합니다.
원활한 업그레이드 중에 이전 마스터는 새 마스터를 생성하고 새 마스터는 이전 마스터의 청취 포트를 상속하며(환경 변수를 통해 청취 소켓에 해당하는 fd 전달) 새 프로세스는 다시 바인딩되지 않습니다. 청취 포트. 신규 작업자와 기존 작업자가 동시에 특정 포트를 수신하는 상황이 있을 수 있습니다. 이 경우 운영 체제는 단 하나의 프로세스만 이벤트를 처리하도록 보장합니다(epoll_wait는 활성화됩니다).
3.3 슬랩을 통해 공유 메모리 관리
nginx를 사용하면 각 모듈이 ngx_http_limit_conn_module 모듈과 같은 공유 공간을 열어 사용할 수 있습니다.
nginx 공유 메모리 관리의 기본 아이디어는 다음과 같습니다.
1. 각 페이지의 크기는 동일하며 여기서는 page_size로 설정됩니다.
2. 2의 정수 거듭제곱에 따라 메모리 블록을 나눕니다. 최소값은 8bit이고 최대값은 page_size/2입니다. 예를 들어, 각 페이지의 크기가 4Kb라고 가정하면 메모리는 8, 16, 32, 64, 128, 256, 512, 1024, 2048의 9가지 유형으로 나누어지며, 이때 각각은 슬롯에 해당합니다. 슬롯 배열의 크기 n은 9입니다. 작은 메모리 블록을 신청할 때(메모리 크기 크기
3. 각 페이지는 한 가지 유형의 메모리 블록으로만 구분됩니다. 예를 들어, 메모리를 신청할 때 기존 메모리는 요구 사항을 충족할 수 없습니다. 이때 새 페이지가 사용되며, 이 새 페이지는 향후 이 크기의 메모리만 할당합니다.
4. 이중 연결 목록을 통해 모든 무료 페이지를 연결합니다. 그림의 ngx_slab_pool_t에 있는 free 변수는 free 페이지를 연결하는 데 사용됩니다.
5. 슬롯 배열을 통해 모든 작은 메모리 블록에서 사용되는 페이지를 연결합니다.
6. 페이지 크기보다 크거나 같은 공간 요청에 대해 필요한 페이지 수를 계산하고, 연속적인 무료 페이지를 찾고, 무료 페이지의 홈페이지 주소를 고객에게 반환하고, ngx_slab_page_t의 관리 구조를 통해 식별합니다. 각 페이지.
7. 모든 페이지에는 무료, 전체 없음, 전체의 3가지 상태만 있습니다. 비어 있는 페이지와 전체가 아닌 페이지는 양방향 연결 목록을 통해 통합됩니다. 공간이 해제되면 전체 페이지가 존재하지 않으며 연결 목록에 추가됩니다.
nginx 공유 메모리의 기본 구조 다이어그램은 다음과 같습니다.
위 그림에서 맨 오른쪽의 ngx_slab_pool_t 인터페이스에서 시작하는 공유 메모리 영역에 위치한 메모리 구간을 제외하면 다른 메모리는 공유 메모리가 아닙니다.
공유 메모리는 궁극적으로 페이지에서 할당됩니다.
위 내용은 Nginx 메모리 관리에 대한 심층적인 이해(그림)의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!