面试题 -- 内存管理

一、自动释放池底层怎么实现

自动释放池以栈的形式实现:
当你创建一个新的自动释放池时,它将被添加到栈顶。当一个对象收到发送autorelease消息时,它被添加到当前线程的处于栈顶的自动释放池中,当自动释放池被回收时,它们从栈中被删除, 并且会给池子里面所有的对象都会做一次release操作。

二、内存的几块区域以及职能

1.栈区

栈区(stack)由编译器自动分配并释放,存放的是函数的参数值,局部变量等,方法调用的实参也是保存在栈区的。
栈区的操作方式类似数据结构中的栈(先进后出)。
栈是系统数据结构,对应线程/进程是唯一的。
优点是快速高效,
缺点是有限制,数据不灵活。
由编译器自动分配释放。主要存放一些基本类型的变量和对象引用类型。

2.堆区

由程序员分配和释放,如果程序员不释放,可能会出现内存泄露,程序结束的时候,可能会由操作系统回收,比如iOS中alloc都是存放在堆中,
堆的操作方式与数据结构中的堆不同,操作方式类似于链表。
优点是灵活方便,数据适应面广泛,但是效率有一定降低,堆空间的分配总是动态的,不同堆分配的内存无法互相操作。
虽然程序结束的时候所有的数据空间都会被释放回系统,但是精确的申请内存,释放内存匹配是良好程序的基本要素。
主要存放用new构造的对象和数组。

3.全局区(静态区)static

全局变量和静态变量是放在一起的,初始化的全局变量和静态变量存放在一块区域,未初始化的全局变量和静态变量在相邻的另一块区域,程序结束后由系统释放。
注意:全局区又可分为未初始化全局区:.bss段和初始化全局区:data段。
举例:int a;为初始化的 int a = 10 ;已初始化的。

4.文字常量区

存放常量字符串。
由编译器管理(分配释放)程序结束后由系统释放。

5.代码区

存放函数的二进制代码

三、ARC通过什么方式帮助开发者管理内存?

通过编译器在编译的时候,插入类似内存管理的代码
ARC相对于MRC,不是在编译时添加retain/release/autorelease这么简单。应该是编译期和运行期两部分共同帮助开发者管理内存。
在编译期,ARC用的是更底层的C接口实现的retain/release/autorelease,这样做性能更好,也是为什么不能再ARC下手动retain/release/autorelease,同时对同一上下文的同一对象的成对retain/release操作进行优化(即忽略掉不必要的操作);ARC也包含运行期组件,这个地方做的优化比较复杂,但也不能被忽略。

最近更新

  1. TCP协议是安全的吗?

    2024-03-11 21:12:04       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-03-11 21:12:04       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-03-11 21:12:04       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-03-11 21:12:04       18 阅读

热门阅读

  1. Qt + mqtt对接阿里云平台(二)

    2024-03-11 21:12:04       23 阅读
  2. 2023 年 3 月青少年软编等考 C 语言一级真题解析

    2024-03-11 21:12:04       22 阅读
  3. Linux信号机制

    2024-03-11 21:12:04       19 阅读
  4. PLIP,openbabel安装避坑

    2024-03-11 21:12:04       29 阅读
  5. LLDB-调试

    2024-03-11 21:12:04       19 阅读
  6. leetcode周赛388(1-3)

    2024-03-11 21:12:04       22 阅读
  7. 网络、UDP编程

    2024-03-11 21:12:04       15 阅读
  8. 安卓 Kotlin 面试题 31-40

    2024-03-11 21:12:04       26 阅读
  9. Rust 泛型使用过程中的 <T> 和 ::<T> 的区别

    2024-03-11 21:12:04       16 阅读