>데이터 베이스 >Redis >Redis zmalloc 함수 예시 분석

Redis zmalloc 함수 예시 분석

PHPz
PHPz앞으로
2023-05-27 17:50:401207검색

Redis 소스 코드(최신 버전 아님)에서 사용자 정의 zmalloc 함수를 직접 살펴보겠습니다. 이 함수는 malloc과 같은 일반 함수와 정확히 동일한 방식으로 사용됩니다. 차이점은 내부 구현 세부 사항에 있습니다.

무효 *zmalloc(size_t size) {

// 메모리 할당

void *ptr = malloc(크기 + PREFIX_SIZE);

// 할당 실패로 인해 예외가 발생합니다.

If (!ptr) zmalloc_oom_handler(size);

// 시스템이 "malloc_size" 함수를 사용할 수 있나요?

#ifdef HAVE_MALLOC_SIZE

Update_zmalloc_stat_alloc(zmalloc_size(ptr));

반환 ptr;

#그밖에

//할당된 데이터의 실제 크기를 데이터 필드에 저장합니다. *((size_t*)ptr) = 크기;

// 정렬 후 메모리 사용량을 계산하고 "used_memory" 변수를 업데이트합니다. Update_zmalloc_stat_alloc(크기 + PREFIX_SIZE);

// 데이터 본문의 초기 위치를 반환합니다.

반환 (문자*)ptr + PREFIX_SIZE;

#엔디프

}

실제로 표준 라이브러리의 malloc 함수는 이미 할당된 메모리를 자동으로 정렬할 수 있으므로 여기서 zmalloc 메서드의 주요 목적은 각 데이터 저장소에 할당된 메모리 크기를 정확하게 계산하는 것입니다. 메모리가 할당될 때마다 zmalloc은 할당된 데이터 메모리 크기에 PREFIX_SIZE 크기의 추가 메모리 공간을 추가합니다. 이 PREFIX_SIZE 매크로는 현재 시스템의 최대 메모리 주소 지정 공간 크기(size_t)를 나타냅니다. 여기서는 이 PREFIX_SIZE 크기 공간을 저장 장치의 "데이터 헤더" 부분으로 참조할 수 있습니다.

Redis

첫 번째 버전의 저장 장치 구조 위 그림과 같이 *((size_t*)ptr) = size; 문을 통해 Redis는 현재 할당된 메모리 블록의 첫 번째 PREFIX_SIZE 바이트, 즉 데이터 헤더에 실제 할당된 데이터 블록 크기를 저장합니다. 다음 바이너리 데이터 엔터티는 실제로 "size" 크기의 메모리 공간에 저장됩니다. 여기서 update_zmalloc_stat_alloc이라는 함수는 내부적으로 Used_memory라는 전역 변수를 유지하며, 매번 새로 할당되는 메모리 크기를 누적합니다. 이 함수는 현재 할당된 메모리의 데이터 본문 부분을 가리키는 오프셋 포인터를 끝에 반환합니다. update_zmalloc_stat_alloc 함수의 구체적인 구현 내용은 다음과 같습니다.

#define update_zmalloc_stat_alloc(__n) do {

size_t _n = (__n)

// 수동 메모리 완성

If (_n&(sizeof(long)-1)) _n += sizeof(long)-(_n&(sizeof(long)-1))

omicIncr(used_memory, __n); } 동안(0)

여기서 주목해야 할 중요한 점은 _n += sizeof(long)-(_n&(sizeof(long)-1)); 라인입니다. 전체 매크로 함수는 먼저 이번에 할당된 메모리 크기가 sizeof(long)의 정수배인지 여부를 결정합니다(64비트 시스템은 8바이트 메모리 정렬에 해당하고 32비트 시스템은 4바이트 메모리 정렬에 해당). 그런 다음 이전에 제공한 명령문을 사용하여 데이터 세그먼트 뒤에 해당 자리 표시자 공간을 추가하여 메모리 정렬(4/8바이트) 요구 사항을 충족하는 비트 수를 구성합니다. 최종 atomicIncr 함수는 스레드 안전성을 보장하면서 전역 Used_memory 변수 값을 업데이트하는 데 사용됩니다.

이 Redis 버전의 메모리 해제 및 메모리 할당 프로세스는 정반대입니다. 아래 표시된 코드는 해당 "zfree" 함수의 구현 세부정보입니다. 먼저 (char*)ptr-PREFIX_SIZE 문을 통해 데이터 블록의 실제 크기가 담긴 데이터 필드의 첫 번째 주소를 가리키고(하위 메모리 주소로 이동), *(( size_t*)realptr) 문입니다. 블록에 의해 할당된 실제 메모리 크기입니다(메모리 정렬 영역 제외). 마지막으로 update_zmalloc_stat_free 함수를 통해 전역 변수 Used_memory의 값을 업데이트하고 메모리 세그먼트를 해제합니다.

void zfree(void *ptr) {

#ifndef HAVE_MALLOC_SIZE

무효 *realptr;

size_t oldsize;

#엔디프

If (ptr == NULL) return;

#ifdef HAVE_MALLOC_SIZE

Update_zmalloc_stat_free(zmalloc_size(ptr));

무료(ptr);

#그밖에

realptr = (char*)ptr-PREFIX_SIZE;

Oldsize = *((size_t*)realptr);

Update_zmalloc_stat_free(이전 크기+PREFIX_SIZE);

무료(realptr);

#엔디프

}

아래와 같이 여기서 update_zmalloc_stat_free 함수의 구현 내용을 살펴보면 이전 update_zmalloc_stat_alloc 함수의 실행 과정과 유사하다는 것을 알 수 있습니다. 보충해야 할 메모리 바이트의 크기를 계산하고 해당 메모리 공간의 크기를 Used_memory 변수에서 빼면 메모리 공간 사용량을 정확하게 계산할 수 있습니다.

#define update_zmalloc_stat_free(__n) do {

size_t _n = (__n)

If (_n&(sizeof(long)-1)) _n += sizeof(long)-(_n&(sizeof(long)-1))

omicDecr(used_memory,__n);

} 동안(0) 

위 내용은 Redis zmalloc 함수 예시 분석의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 yisu.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제