iOS 원리 alloc 핵심 단계 2:calloc 상세 설명
전언
calloc
방법은alloc프로세스의 핵심 절차 중 하나로서 주요 기능은 대상에게 메모리 공간을 분배하고 이 메모리 주소를 가리키는 지침을 되돌려주는 것이다.앞의 학습을 통해 우리는 instacnceSize
방법에서 대상이 신청해야 할 메모리 크기를 계산해 냈는데 그 시스템이 대상을 대상으로 실제 분배한 메모리 크기와 신청해야 할 메모리 크기가 같다는 것을 알 수 있습니까?다음에 본고는 calloc
방법에서 시스템이 메모리에 대해 어떻게 처리했는지 상세하게 설명할 것이다.1.calloc 방법의 메모리 처리 분석
lloc 방법의 밑바닥은 논리를 실현하기 때문에
libmalloc
원본에서 보아야 하기 때문에 애플 원본 사이트에서libmalloc 원본의 최신 버전을 다운로드해야 한다.본고는 libmalloc-283.100.6
원본을 바탕으로 분석한 것이다. 여기서calloc의 메모리 처리 논리만 설명하고calloc 방법의 실현 절차에 관심이 있으면 스스로 중단점을 끊고 절차 추적을 할 수 있다.libmalloc 원본에서 프로세스 추적을 통해calloc 프로세스는 최종적으로
segregated_size_to_fit
방법에서 신청한 메모리 크기를 재처리한 것을 알 수 있다.#define SHIFT_NANO_QUANTUM 4
#define NANO_REGIME_QUANTA_SIZE (1 << SHIFT_NANO_QUANTUM) // 16
static MALLOC_INLINE size_t
segregated_size_to_fit(nanozone_t *nanozone, size_t size, size_t *pKey)
{
size_t k, slot_bytes;
//step1
if (0 == size) {
size = NANO_REGIME_QUANTA_SIZE; // Historical behavior
}
//step2
k = (size + NANO_REGIME_QUANTA_SIZE - 1) >> SHIFT_NANO_QUANTUM; // round up and shift for number of quanta
slot_bytes = k << SHIFT_NANO_QUANTUM; // multiply by power of two quanta size
*pKey = k - 1; // Zero-based!
return slot_bytes;
}
코드에서 알 수 있듯이 마지막으로 실제 분배된 메모리 크기는 slot 이다bytes, 총 2단계 처리:
이것은 이전에 신청한 메모리 공간의 크기를 판단하는 것입니다. 만약 크기가 0이 되지 않으면 크기를 16으로 부여합니다.
NANO_REGIME_QUANTA_SIZE
의 값은 16으로 1을 네 자리로 왼쪽으로 옮기는 것을 통해 얻어진다.0000 0001 //1
0001 0000 //1 << 4 = 16
여기는size를 먼저 15를 더하고 오른쪽으로 4자리를 옮겨 k값을 얻은 다음에 k를 왼쪽으로 4자리를 옮겨 슬로트bytes.사이즈의 값이 24라고 가정하면 마지막으로 계산한 슬로트bytes 값은 얼마입니까?
0001 1000 //24
0000 1111 //15
0010 0111 //24 + 15 = 39
0000 0010 //39 >> 4 = 2 (k)
0010 0000 //2 << 4 = 32 (slot_bytes)
계산을 통해 알 수 있듯이size가 24일 때 마지막에 얻은 slotbytes는 32입니다. 이것은 시스템이 대상을 대상으로 실제 분배하는 메모리 공간의 크기입니다.계산 논리에서 알 수 있듯이
segregated_size_to_fit
방법은 신청한 메모리 크기를'16 바이트 정렬'하고 최종적으로 16 바이트의 배수로 공간을 분배하며 최소 16 바이트를 분배한다.2. 검증calloc 방법의 메모리 처리
위에서 설명한calloc 방법은 신청한 메모리 크기를 16바이트로 정렬하여 Person 대상을 만들어 검증합니다.
malloc_size
방법을 통해 시스템을 대상으로 실제 개척된 메모리 크기를 얻을 수 있으며, 호출할 때 먼저 #import
가 필요합니다.//Person
@interface Person : NSObject
@property (nonatomic, strong) NSString *name; //8
@property (nonatomic, strong) NSString *sex; //8
@property (nonatomic, assign) int age; //4
@property (nonatomic, assign) long height; //8
@property (nonatomic) char c1; //1
@property (nonatomic) char c2; //1
@end
// Person ,
Person *person = [[Person alloc] init];
NSLog(@" :%lu", malloc_size((__bridge const void *)(person)));
코드에서 보듯이 개인 대상의 모든 속성이 차지하는 메모리 공간 크기는 38바이트이며, 대상을 만든 후
malloc_size
방법을 통해 실제 분배된 메모리 공간 크기를 가져와 인쇄합니다.calloc
방법의 메모리 처리 논리를 검증하기 위해 class_createInstanceFromZone
방법에서 신청한 메모리 공간 크기를 먼저 출력한다.static ALWAYS_INLINE id
_class_createInstanceFromZone(Class cls, size_t extraBytes, void *zone,
int construct_flags = OBJECT_CONSTRUCT_NONE,
bool cxxConstruct = true,
size_t *outAllocatedSize = nil)
{
ASSERT(cls->isRealized());
// Read class's info bits all at once for performance
bool hasCxxCtor = cxxConstruct && cls->hasCxxCtor();
bool hasCxxDtor = cls->hasCxxDtor();
bool fast = cls->canAllocNonpointer();
//1:
size_t size;
size = cls->instanceSize(extraBytes);
if (outAllocatedSize) *outAllocatedSize = size;
// size
printf(" :%lu
", size);
//2. ,
id obj;
if (zone) {
obj = (id)malloc_zone_calloc((malloc_zone_t *)zone, 1, size);
} else {
//zone nil,
obj = (id)calloc(1, size);
}
if (slowpath(!obj)) {
if (construct_flags & OBJECT_CONSTRUCT_CALL_BADALLOC) {
return _objc_callBadAllocHandler(cls);
}
return nil;
}
//3 。
if (!zone && fast) {
obj->initInstanceIsa(cls, hasCxxDtor);
} else {
// Use raw pointer isa on the assumption that they might be
// doing something weird with the zone or RR.
obj->initIsa(cls);
}
if (fastpath(!hasCxxCtor)) {
return obj;
}
construct_flags |= OBJECT_CONSTRUCT_FREE_ONFAILURE;
return object_cxxConstructFromClass(obj, cls, construct_flags);
}
앞의 학습을 통해 알 수 있듯이
instanceSize
방법에서 신청해야 할 메모리 크기의 계산을 완성하였다.비교를 더욱 직관적으로 하기 위해 16자 바이트 정렬과 8자 바이트 정렬을 통해 계산된 결과를 출력합니다.//objc-781 instanceSize
size_t instanceSize(size_t extraBytes) const {
// : (16 )
if (fastpath(cache.hasFastInstanceSize(extraBytes))) {
return cache.fastInstanceSize(extraBytes);
}
// : + 0(8 )
size_t size = alignedInstanceSize() + extraBytes;
//CF requires all objects be at least 16 bytes.
// 16
if (size < 16) size = 16;
return size;
}
최신
objc-781
소스에서는 16바이트 정렬 방식을 통해 다음과 같이 인쇄됩니다. :48
:48
//objc-750 instanceSize
size_t instanceSize(size_t extraBytes) {
size_t size = alignedInstanceSize() + extraBytes;
// CF requires all objects be at least 16 bytes.
if (size < 16) size = 16;
return size;
}
이전 버전의
objc-750
소스에서 8바이트 정렬 방식을 사용했기 때문에 인쇄 결과는 다음과 같습니다. :40
:48
상기 두 가지 정렬 방식의 인쇄 결과를 비교해 보면
calloc
방법은 신청한 메모리 크기를 16바이트 정렬 처리하고 되돌아오는 결과는 시스템이 실제 대상에게 분배한 메모리 공간 크기이다.3. 총결산
alloc가 대상을 만들 때 시스템은
instanceSize
방법으로 얼마나 큰 메모리 공간을 신청해야 하는지를 계산한 다음calloc
방법에서 신청한 메모리 크기를 16바이트 정렬 처리한 다음에 처리 후의 결과에 따라 대상에게 메모리 공간을 분배하고 메모리 주소로 되돌려준다.시스템이 최종적으로 대상을 위해 분배한 메모리 공간의 크기는 16바이트의 전체 수배이고 최소 16바이트이다. instanceSize
방법에서 16바이트로 맞추면 실제 분배된 메모리 크기와 신청한 메모리 크기가 같고 8바이트로 맞추면 다르다.추천
1. iOS 원리 OC 대상의 실례화 2.iOS 원리 alloc 핵심 단계 1:instanceSize 상세 설명 3.iOS 원리alloc 핵심 3: initInstanceIsa 상세 설명
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.