AutoReleasePoolTestExample
AutoReleasePoolTestExample copied to clipboard
如果屏蔽[NSString stringWithFormat:@"%@%@", num, str]; 没有显示添加autoreleasepool内存不会突增
情况1:Run loop without autoReleasePool中把下面代码屏蔽,运行demo,没有内存突增
//[NSString stringWithFormat:@"%@%@", num, str];

反编译伪代码代码
void __cdecl _26__ViewController_runTest___block_invoke_14(__block_literal_2 *.block_descriptor)
{
void *v1; // rax
void *v2; // rax
Foundation::NSArray::NSMutableArray *v3; // ST18_8
double v4; // xmm0_8
void *v5; // rax
__int64 v6; // ST08_8
Foundation::NSString::NSString *str; // [rsp+38h] [rbp-28h]
Foundation::NSValue::NSNumber *num; // [rsp+40h] [rbp-20h]
int i; // [rsp+4Ch] [rbp-14h]
__block_literal_2 *v10; // [rsp+50h] [rbp-10h]
__block_literal_2 *_block_descriptor; // [rsp+58h] [rbp-8h]
_block_descriptor = .block_descriptor;
v10 = .block_descriptor;
for ( i = 0; i < 500000; ++i )
{
v1 = objc_msgSend(&OBJC_CLASS___NSNumber, "numberWithInt:", (unsigned int)i);
num = (Foundation::NSValue::NSNumber *)objc_retainAutoreleasedReturnValue(v1);
v2 = objc_msgSend(&OBJC_CLASS___NSString, "stringWithFormat:", CFSTR("%d "), (unsigned int)i);
str = (Foundation::NSString::NSString *)objc_retainAutoreleasedReturnValue(v2);
if ( !(i % 50000) )
{
v3 = (&.block_descriptor->self->_memoryUsageList2)[3];
v4 = getMemoryUsage();
v5 = objc_msgSend(&OBJC_CLASS___NSNumber, "numberWithDouble:", v4);
v6 = objc_retainAutoreleasedReturnValue(v5);
objc_msgSend(v3, "addObject:", v6);
objc_release(v6);
}
objc_storeStrong(&str, 0LL);
objc_storeStrong(&num, 0LL);
}
}
情况2:或者将屏蔽代码改为,结果和上面一样,也没有内存突增
[NSString stringWithFormat:@"%@", str];
反编译伪代码代码
void __cdecl _26__ViewController_runTest___block_invoke_14(__block_literal_2 *.block_descriptor)
{
void *v1; // rax
void *v2; // rax
Foundation::NSString::NSString *v3; // rax
void *v4; // rax
__int64 v5; // rax
Foundation::NSArray::NSMutableArray *v6; // ST18_8
double v7; // xmm0_8
void *v8; // rax
__int64 v9; // ST08_8
Foundation::NSString::NSString *str; // [rsp+38h] [rbp-28h]
Foundation::NSValue::NSNumber *num; // [rsp+40h] [rbp-20h]
int i; // [rsp+4Ch] [rbp-14h]
__block_literal_2 *v13; // [rsp+50h] [rbp-10h]
__block_literal_2 *_block_descriptor; // [rsp+58h] [rbp-8h]
_block_descriptor = .block_descriptor;
v13 = .block_descriptor;
for ( i = 0; i < 500000; ++i )
{
v1 = objc_msgSend(&OBJC_CLASS___NSNumber, "numberWithInt:", (unsigned int)i);
num = (Foundation::NSValue::NSNumber *)objc_retainAutoreleasedReturnValue(v1);
v2 = objc_msgSend(&OBJC_CLASS___NSString, "stringWithFormat:", CFSTR("%d "), (unsigned int)i);
v3 = (Foundation::NSString::NSString *)objc_retainAutoreleasedReturnValue(v2);
str = v3;
v4 = objc_msgSend(&OBJC_CLASS___NSString, "stringWithFormat:", CFSTR("%@%@"), num, v3);
v5 = objc_retainAutoreleasedReturnValue(v4);
objc_release(v5);
if ( !(i % 50000) )
{
v6 = (&.block_descriptor->self->_memoryUsageList2)[3];
v7 = getMemoryUsage();
v8 = objc_msgSend(&OBJC_CLASS___NSNumber, "numberWithDouble:", v7);
v9 = objc_retainAutoreleasedReturnValue(v8);
objc_msgSend(v6, "addObject:", v9);
objc_release(v9);
}
objc_storeStrong(&str, 0LL);
objc_storeStrong(&num, 0LL);
}
}
情况3:
// [NSString stringWithFormat:@"%@%@", num, str];
[NSString stringWithFormat:@"1%@人", str];
[NSString stringWithFormat:@"2%@", num];
这时候出现的内存的突增
在不采取autoreleasepool的情况下,基于上面3种操作,请问为什么内存的表现不一样? 请问这是ARC内部自动帮我们优化的吗?如果是对unused warnning优化,那么第二种情况和第一种一样呢?个人怀疑是NSString构造(或者说是对象的构造)实现有关系。望回答