影响对象内存的因素
思考:影响对象内存的因素有哪些?属性、成员变量、方法 ?
@interface ABPerson : NSObject
@end
ABPerson没有添加任何属性、成员变量、方法,输出是8,这是isa占用的8个字节
添加方法后:
依然是8,所以方法不占用对象内存
添加属性:
@interface ABPerson : NSObject
@property (nonatomic,strong) NSString *nickName;
@end
去掉isa占用的8个字节,当前属性也占用8个字节
添加成员变量:
@interface ABPerson : NSObject
{
NSString *_nickName;
}
@end
成员变量也是占用内存的。
所以,影响对象内存的是属性、成员变量,方法不占用对象内存。
对象的内存布局
lldb查看ABPerson对象的内存布局
@interface ABPerson : NSObject
-(void)doSomething;
@end
@interface ABPerson : NSObject
{
char _c3;
}
@property (nonatomic,strong) NSString *nickName;
@property (nonatomic,assign) int age;
@property (nonatomic) char c1;
@property (nonatomic) char c2;
@end
#import "ABPerson.h"
@implementation ABPerson
- (instancetype)init
{
self = [super init];
if (self) {
_c3 = 'c';
}
return self;
}
@end
#import <UIKit/UIKit.h>
#import "AppDelegate.h"
#import "ABPerson.h"
#import <objc/runtime.h>
int main(int argc, char * argv[]) {
NSString * appDelegateClassName;
@autoreleasepool {
ABPerson *p = [[ABPerson alloc] init];
p.nickName = @"王";
p.age = 18;
p.c1 = 'a';
p.c2 = 'b';
NSLog(@"%zu",class_getInstanceSize(ABPerson.class));//24
appDelegateClassName = NSStringFromClass([AppDelegate class]);
}
return UIApplicationMain(argc, argv, nil, appDelegateClassName);
}
a、b、c的ASCII码分别是97、98、99,所以年龄、c1、c2、c3共用了这8个字节,这就是结构体内存对齐
结构体内存对齐
内存对齐原则
- 数据成员对⻬规则:结构(struct)(或联合(union))的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员存储的起始位置要从该成员大小或者成员的子成员大小(只要该成员有子成员,比如说是数组,结构体等)的整数倍开始(比如int为4字节,则要从4的整数倍地址开始存储。
- 结构体作为成员:如果一个结构里有某些结构体成员,则结构体成员要从其内部最大元素大小的整数倍地址开始存储.(struct a里存有structb,b里有char,int ,double等元素,那b应该从8的整数倍开始存储.)
- 收尾工作:结构体的总大小,也就是sizeof的结果,必须是其内部最大成员的整数倍.不足的要补⻬。
struct ABStruct1 {
double a; //8 [0...7]
char b; //1 [8]
int c; //4 9,10,11,[12,13,14,15]
short d; //2 [16,17]
}struct1; //24
struct ABStruct2 {
double a; //8 [0...7]
int b; //4 [8,9,10,11]
char c; //1 [12]
short d; //2 13,[14,15]
}struct2; //16
struct ABStruct3 {
double a; //8 [0...7]
int b; //4 [8,9,10,11]
char c; //1 [12]
short d; //2 13,[14,15]
int e; //4 [16,17,18,19]
struct ABStruct1 str; //24 20,21,22,23,[24...47],
}struct3; //48
注释代码部分,分别是不同类型变量所占字节大小,和占用内存空间的索引。
按照内存对齐原则
,分析ABStruct1的结构体内存对齐:
a
是double类型占用8个字节,占用索引0到7,b
是char类型占用1个字节,索引位置必须是当前类型(char类型)的整数倍,接下来的索引8是1的倍数,b占用索引8,c
是int类型占用4个字节,接下来的索引9,10,11都不是4的倍数,索引12是,所以c占用索引12到15d
是short类型占用2个字节,索引16是2的倍数,所以d占用索引16、17- 又因为结构体的总大小必须是其内部最大成员的整数倍.不足的要补⻬,满足索引最大成员8的倍数又要装下所有变量的最小值就是24
同理ABStruct1是16,ABStruct3是48 代码验证: