美文网首页
堆栈 存储空间

堆栈 存储空间

作者: 纳兰沫 | 来源:发表于2019-01-23 15:12 被阅读9次

参考文献

iOS--------对堆、栈 存储空间的理解

局部变量、 全局变量、 堆、 堆栈、 静态和全局

iOS之NSString的内存

- Objective-C的对象在内存中是以堆的方式分配空间的 并且堆空间是由你释
放的 即release 
- 栈由编译器管理自动释放的 在方法中(函数体)定义的变量通常在栈内 
"因此如果你的变量要跨函数的话,就需要将其定义为成员变量"

运行代码使用的在三个不同的内存区域

1.text segment 是应用程序运行时应用程序代码存在的内存段 每
一个指令 每一个单个函数 过程 方法和执行代码都存在这个内存段中直到应
用程序退出
2.stack segment(栈区) 先进后出结构 
3.heap segment(堆区) 提供一个保存中介贯穿函数的执行过程 全局和静态
变量保存在heap中 直到应用退出

为了访问你创建在heap中的数据 你最少要求有一个保存在stack中的指针 因为你的CPU通过stack中的指针访问heap中的数据
操作系统使用stack段中的指针访问heap段中的对象 如果stack对象的指针没有了 则heap中的对象就不能访问了 这就是内存泄漏的原因

栈区

栈区 由编译器自动分配释放 存放函数的参数值 局部变量等值 其操作方式类
似于数据结构中的栈

stack 对象

stack 对象的优点
1 创建速度快
2 简单管理 有严格的生命周期
stack 对象的缺点
- 不灵活 创建时长度是多长就一直是多大 创建时哪个函数创建的 它的owner
就一直是它 不像heap对象那样有多个owner  其实多个owner 等同于引用计
数 只有heap对象才是采用"引用计数"方法管理它
stack 对象的创建
只要栈的剩余空间大于stack 对象申请创建的空间 操作系统就会为程序提供
这段内存空间 否则将报异常提示栈溢出

堆区

堆区 一般由程序员分配释放 若程序员不释放 则可能会引起内存泄漏 注堆和
数据结构中的堆栈不一样 其类似于链表

heap 对象

heap 对象的创建
操作系统对于内存heap段是采用链表进行管理的 操作系统有一个记录空闲内
存地址的链表 当收到程序的申请时 会遍历链表 寻找第一个空间大于所申请的
heap节点 然后将该节点从空闲链表中删除 并将该节点的空间分配给程序

申请大小

栈 stack 在windows下 栈是由低地址扩展的数据结构 是一块连续的内存区
域(栈顶上的地址和栈的最大容量是系统预先规定好的) 在windows下 栈的大
小是2M  如果申请的空间超出了栈的剩余空间的时候 就overflow 因此 能获
得栈的空间较小
堆 heap 堆是向高地址扩展的数据结构 是不连续的区域 这是由于系统是用链
表来存储的空闲内存地址的 自然是不连续的 而链表的遍历方向是由低地址向
高地址 堆的大小受限于计算机系统中有效的虚拟内存 因此 堆获得的空间比较
灵活 也比较大

碎片问题

对于堆来讲,频繁的new/delete势必会造成内存空间的不连续,从而造成大量
的碎片,使程序效率降低。对于栈来讲,则不会存在这个问题,因为栈是先进
后出的队列,他们是如此的一一对应,以至于永远都不可能有一个内存快从栈
中弹出

分配方式

- 堆都是动态分配的 
- 栈有两种分配方式 静态分配和动态分配 
  1.静态分配是编译器完成的 比如局部变量的分配 
  2.动态分配是alloc函数进行分配的 但是栈的动态分配和堆是不同的 他的
动态分配由编译器进行释放 无需我们手工实现

分配效率

- 栈是机器系统提供的数据结构 计算机会在底层堆栈提供支持 分配专门的寄
存器放栈的地址 压栈出栈都有专门的指令执行 这就决定了栈的效率比较高
- 堆是C/C++函数库提供的 机制比较复杂

一个由C/C++编译的程序占用的内存分为以下几个部分

1.栈区(stack) 由编译器自动分配释放  释放函数的参数值 局部变量的值等
2.堆区(heap) 由程序员分配和释放 若程序员不释放 程序结束时可能由OS
回收
3.全局区(静态区)  全局变量和静态变量的存储是放在一块的 初始化的全局
变量和静态变量在一块区域 未初始化的全局变量 未初始化的静态变量在相邻
另一块区域
4.文字常量区 常量字符串就是放在这里
5.程序代码区 存放函数体的二进制代码 

NSString 内存

@"xxx" 方法生成的字符串分配在常量区 系统自动管理内存 在栈区
initWithFormat: 和 stringWithFormat: 方法生成的字符串分配在堆区
    NSString *a0 = @"aaa";
    NSString *a1 = [NSString stringWithString:a0];
    NSString *a2 = [[NSString alloc] initWithString:a0];
    NSString *a3 = [[NSString alloc] initWithFormat:@"%@", a0];
    NSString *a4 = [[NSString alloc] initWithFormat:@"aaa"];
    NSString *a5 = [[NSString alloc] initWithFormat:@"b%@", a0];
    NSString *a6 = [[NSString alloc] initWithString:a5];
    NSString *a7 = [[NSString alloc] initWithString:a3];
    
    NSLog(@"\na0=~~~~%p\na1=~~~~%p\na2=~~~~%p\na3=~~~~%p\na4=~~~~%p\na5=~~~~%p\na6=~~~~%p\na7=~~~~%p", a0, a1, a2, a3, a4, a5, a6, a7);

打印结果:
a0=~~~~0x107208078
a1=~~~~0x107208078
a2=~~~~0x107208078
a3=~~~~0xa000000006161613
a4=~~~~0xa000000006161613
a5=~~~~0xa000000616161624
a6=~~~~0x60000004d6e0
a7=~~~~0x60000004d3e0

(lldb) p a0
(__NSCFConstantString *) $0 = 0x0000000107208078 @"aaa"
(lldb) p a1
(__NSCFConstantString *) $1 = 0x0000000107208078 @"aaa"
(lldb) p a2
(__NSCFConstantString *) $2 = 0x0000000107208078 @"aaa"
(lldb) p a3
(NSTaggedPointerString *) $3 = 0xa000000006161613 @"aaa"
(lldb) p a4
(NSTaggedPointerString *) $4 = 0xa000000006161613 @"aaa"
(lldb) p a5
(NSTaggedPointerString *) $5 = 0xa000000616161624 @"baaa"
(lldb) p a6
(__NSCFString *) $6 = 0x000060000004d6e0 @"baaa"
(lldb) p a7
(__NSCFString *) $7 = 0x000060000004d3e0 @"aaa"
(lldb) 

相关文章

  • 堆栈 存储空间

    参考文献 iOS--------对堆、栈 存储空间的理解 局部变量、 全局变量、 堆、 堆栈、 静态和全局 iOS...

  • 11/15

    c语言在内存中工作时分为堆栈,bss,data,code等区。功能和释放都有不同的定义。堆是人来开辟的存储空间,由...

  • 堆,栈深入理解

    上图是进程的虚拟地址空间示意图。 堆栈段: 1 为函数内部的局部变量提供存储空间。 2 进行函数调用时,存储“过...

  • Go 堆栈的理解

    在讲Go的堆栈之前,先温习一下堆栈基础知识。 什么是堆栈?在计算机中堆栈的概念分为:数据结构的堆栈和内存分配中堆栈...

  • 三种常见的计算模型

    堆栈机 堆栈机,全称为“堆栈结构机器”,即英文的 “Stack Machine”。基于堆栈机模型实现的计算机,无论...

  • 初识堆栈

    什么是堆栈 引出堆栈 在学习堆栈之前,我们需要从之前寄存器和内存中引出堆栈,我们要思考堆栈有什么必要性?现在假设我...

  • Linux内核——用户堆栈和内核堆栈

    定义 每个进程都有用户堆栈和内核堆栈两个堆栈。进程在用户态时使用用户堆栈,陷入到内核态时便使用内核堆栈。 切换过程...

  • 数据结构和算法(三) - 栈

    堆栈数据结构在概念上与物理的堆栈相同。将元素添加到堆栈时,将其放在堆栈顶部。从堆栈中删除元素时,始终会删除最顶层的...

  • crash之野指针

    例子一 堆栈信息 根据堆栈分析:1,野指针2,有对应的堆栈查看堆栈代码,看那些有可能野指针: 分析所有参数:url...

  • ARM栈结构

    ARM 栈类型 根据栈生长方向,ARM的栈可分为递增堆栈和递减堆栈。 递增堆栈:栈向高地址生长 递减堆栈:栈向低地...

网友评论

      本文标题:堆栈 存储空间

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