美文网首页iOS Developer
在内存剖析对象

在内存剖析对象

作者: 杭城小刘 | 来源:发表于2017-05-16 00:26 被阅读209次

对象在内存中的存储

  • 栈、堆、BSS、数据段、代码段是什么?

    • 栈(stack):又称作堆栈,用来存储程序的局部变量(但不包括static声明的变量,static修饰的数据存放于数据段中)。除此之外,在函数被调用时,栈用来传递参数和返回值。

    • 堆(heap):用于存储程序运行中被动态分配的内存段,它的大小并不固定,可动态的扩张和缩减。操作函数(malloc/free)

    • BSS段(bss segment):通常用来存储程序中未被初始化的全局变量和静态变量的一块内存区域。BSS是英文Block Started by Symbol的简称。BSS段输入静态内存分配

    • 数据段(data segment):通常用来存储程序中已被初始化的全局变量和静态变量和字符串的一块内存区域

    • 代码段(code segment):通常是指用来存储程序可执行代码的一块内存区域。这部分区域的大小在程序运行前就已经确定,并且内存区域通常属于只读,某些架构也允许代码段为可写,即允许修改程序。在代码段中,也有可能包含一些只读的常数变量,例如字符串常量。

内存内存
  • 搞清楚上面的概念再来研究下对象在内存中如何存储?
Person *p1 = [Person new]

看这行代码,先来看几个注意点:

  • new底层做的事情:

    • 在堆内存中申请1块合适大小的空间

    • 在这块内存上根据类模版创建对象。类模版中定义了什么属性就依次把这些属性声明在对象中;对象中还存在一个属性叫做isa,是一个指针,指向对象所属的类在代码段中地址

    • 初始化对象的属性。这里初始化有几个原则:a、如果属性的数据类型是基本数据类型则赋值为0;b、如果属性的数据类型是C语言的指针类型则赋值为NULL;c、如果属性的数据类型为OC的指针类型则赋值为nil。

    • 返回堆空间上对象的地址

  • 注意

    • 对象只有属性,没有方法。包括类本身的属性和一个指向代码段中的类isa指针

    • 如何访问对象的属性?指针名->属性名;本质:根据指针名找到指针指向的对象,再根据属性名查找来访问对象的属性值

    • 如何调用方法?[指针名 方法];本质:根据指针名找到指针指向的对象,再发现对象需要调用方法,再通过对象的isa指针找到代码段中的类,再调用类里面方法

  • 为什么不把方法存储在对象中?

    • 因为以类为模版创建的对象只有属性可能不相同,而方法相同,如果堆区的对象里面也保存方法的话就会很重复,浪费了堆空间,因此将方法存储与代码段

    • 所以一个类创建的n个对象的isa指针的地址值都相同,都指向代码段中的类地址

做个小实验

#import <Foundation/Foundation.h>
@interface Person : NSObject{
    @public
    int _age;
    NSString *_name;
    int *p;
}

-(void)sayHi;
@end

@implementation Person

-(void)sayHi{
    NSLog(@"Hi, %@",_name);
}

@end

int main(int argc, const char * argv[]) {
    Person *p1 = [Person new];
    Person *p2 = [Person new];
    Person *p3 = [Person new];
    p1->_age = 20;
    p2->_age = 20;

    [p1 sayHi];
    [p2 sayHi];
    [p3 sayHi];

    return 0;
}
Person  *p1 = [Person new];

这句代码在内存分配原理如下图所示

p1p1

结论

p1p1 p3p3

可以 看到Person类的3个对象p1、p2、p3的isa的值相同。

相关文章

  • Java对象内存分析

    此处对象内存分析只针对Java基本对象,暂不对集合对象进行剖析。 内存 栈内存 堆内存

  • 在内存剖析对象

    对象在内存中的存储 栈、堆、BSS、数据段、代码段是什么?栈(stack):又称作堆栈,用来存储程序的局部变量(但...

  • Java 自定义对象内存图

    自定义类 属于引用数据类型 它创建出的对象在 堆内存中开辟内存空间(内存中包括对象的属性 ) 对象调用方法就是在 ...

  • Java对象

    Java对象的内存布局?对象的访问?new对象的过程? 一、Java对象的内存布局 对象的创建过程就是在堆上分配实...

  • JVM 常见内容汇总

    面试题 对象 对象的创建 分配内存 对象头 内存溢出 内存溢出与内存泄漏 内存溢出:系统无法再分配内存空间。 内存...

  • OOM

    概念 内存溢出 - VM在分配内存时内存不足导致内存溢出 内存泄漏 - 有对象在释放时没有完全...

  • JVM分析利器,JProfiler 9.1.1部署及使用,多图杀

    JProfiler是一款强大的商业JAVA分析工具,可以进行内存剖析,堆遍历、CPU剖析、线程剖析、VM 遥感勘测...

  • 创建一个对象用什么运算符?对象实体与对象引用有何不同?

    new运算符,new创建对象实例(对象实例在堆内存中),对象引用指向对象实例(对象引用存放在栈内存中)。一个对象引...

  • JVM中 对象的内存布局 以及 实例分析

    对象内存结构 在 HotSpot 虚拟机中,对象在内存中存储的布局可以分为3块区域:① 对象头(Header)② ...

  • 浅拷贝与深拷贝

    写在前面 浅拷贝:指向对象所在内存指针的拷贝,对象所在内存不变 深拷贝:对象所在内存重新拷贝一份 在 iOS 中,...

网友评论

    本文标题:在内存剖析对象

    本文链接:https://www.haomeiwen.com/subject/aypkxxtx.html