【iOS】iOS内存五大分区

iOS内存五大分区

总揽

iOS中,内存主要分为五大区域:栈区,堆区,全局区/静态区,常量区和代码区。总览图如下。
在这里插入图片描述

这个图我觉得更好记,因为下面是低地址,上面是高地址,是比较符合日常逻辑的。
由下到上开始背:代码区,常量区,全局/静态区,堆区(向上生长),栈区(向下生长),内核区

如上图所示,代码区是在低地址段存放,而栈区则存放在高地址段,并且各个分区之间不是连续的。

栈区

1.1 介绍

  • 栈是从高地址向低地址存储的一块连续的内存区域,特点是先进后出(FILO)
  • 栈的地址空间在iOS里面 0X7 / 0X16 开头
  • 栈区一般是在 运行时分配内存,内存空间由系统管理, 也就是变量超出了自身的作用范围之后就会被释放
  • 包含 函数内部定义的局部变量以及方法参数(方法的默认参数self、cmd)等也都是存放在栈区

1.2优缺点

  • 注意,栈区的内存是由系统分配并管理的,所以它会由系统分配并自己释放,不会产生内存碎片,更快更高效。
  • 但是栈的内存大小被系统所限制导致其并不是很灵活,iOS主线程栈道大小1MB,其他线程512KB,Mac为8M
    在这里插入图片描述
- (void)testStack {int a = 10;NSLog(@"a == %p size == %lu",&a,sizeof(a));NSLog(@"方法参数 self:%p",&self);NSLog(@"方法参数 cmd:%p",&_cmd);
}

在这里插入图片描述

可以看出,栈内存的分配是连续的参数如栈顺序为,self, _cmd, a。然后地址的大小变化为0x16b8cba28 -> 0x16b8cba20 -> 0x16b8cba1c (可以看出由高地址到低地址,一次递减8字节

堆区

  • 堆是从低地址向高地址的不连续的内存区域,和链表的结构很相似(便于增删但不便于查询),特点是先进先出(FIFO)
  • 堆地址是以0x6开头,动态的分配空间
  • 在堆里面存放的东西需要我们手动的管理和释放,若不及时释放就会造成内存泄漏
  • 在OC里面alloc和new都会为对象开辟空间到堆上
- (void)testHeap {NSObject *object1 = [NSObject new];NSObject *object2 = [NSObject new];NSLog(@"object1 = %@",object1);NSLog(@"object2 = %@",object2);
}

在这里插入图片描述

可以看出,堆内存分配是 不连续的

栈和堆的区别联系

  1. 各自的优缺点?
  • 栈:由编译器自动分配并释放,速度较快,不会产生内存碎片。优点是快速高效,缺点是有限制,数据不灵活。
  • 堆: 由程序员分配和释放,速度比较慢,而且容易产生内存碎片,不过用起来最方便。优点是灵活方便,数据适应面广泛,但是效率有一定降低
  1. 申请后的系统如何响应?
  • 栈:存储每一个函数在执行的时候都会向操作系统索要资源,栈区就是函数运行时的内存,栈区中的变量由编译器负责分配和释放,内存随着函数的运行分配,随着函数的结束而释放,由系统自动完成。只要栈的剩余空间大于所申请空间,系统将为程序提供内存,否则将报异常提示栈溢出。
  • 堆:操作系统有一个记录空闲内存地址的链表。当系统收到程序的申请时,会遍历该链表,寻找第一个空间大于所申请空间的堆结点,然后将该结点从空间结点链表中删除,并将该结点的空间分配给程序。由于找到的堆结点的大小不一定正好等于申请的大小,系统会自动的将多余的那部分重新放入空闲链表中。
  1. 申请大小的限制?
  • 栈: 栈是向低地址扩展的数据结构,是一块连续的内存的区域。栈顶的地址和栈的最大容量是系统预先规定好的,栈的大小是2M(有的说是1M,总之是一个编译时就确定的常数),如果申请的空间超过栈道剩余空间时,将提示overflow。因此,能从栈获得的空间较小。
  • 堆: 堆是向高地址扩展的数据结构,是不连续的内存区域。这是由于系统是用链表来存储空闲内存地址的,自然是不连续的,而链表的遍历方向是由低地址向高地址。堆的大小受限于计算机系统中有效的虚拟内存。由此可见,堆获得的空间比较灵活,也比较大。

全局/静态区

  • 该区是编译时分配的内存空间,在iOS中一般以0x1开头,在程序运行过程中,此内存中的数据一直存在,程序结束后由系统释放。
  • 未初始化的全局变量和静态变量,即BSS区(.bss)。
  • 已初始化的全局变量和静态变量,即数据区(.data)。

其中,全局变量是指变量值可以在运行时被动态修改,而静态变量是static修饰的变量,包含静态局部变量和静态全局变量

int clB;
static int bssB;
int initClB = 10;
static int initBssB = 11;
- (void)testStatic {NSLog(@"clA = %p", &clB);NSLog(@"bssB = %p", &bssB);NSLog(@"initClB = %p", &initClB);NSLog(@"initBssB = %p", &initBssB);
}

在这里插入图片描述

结论:
clB 和 bssB都是未初始化,在内存是连续的地址,相差为4。
initClB和 initBssB都是初始化的数据,内存地址也是连续的,也相差4。

常量区

  • 该区是编译时分配的内存空间,在程序运行过程中,此内存中的数据一直存在,程序结束后由系统释放。
  • 存放常量: 整形、字符型、浮点、字符串等
  • 常量区是编译时分配的内存空间,在程序结束后由系统释放,主要存放:
    • 已经使用了的,且没有指向的字符串常量
    • 字符串常量因为可能在程序中被多次使用,所以在程序运行之前,就回提前分配内存。

代码区

  • 该区时编译时分配的内存空间,在程序运行过程中,此内存中的数据一直存在,程序结束后由系统释放
  • 程序运行时的代码会被编译成二进制,存进内存的代码区域

面试题

  1. 讲一下static关键字的各种情况以及作用

答:

  • 对于全局变量来说,static 改变了其作用域。普通全局变量是所有文件都可以用。静态全局变量是只有当前文件可以用。
  • 对于局部变量来说,static改变了其存储方式从而改变了生命周期。普通局部变量是动态存储,动态存储决定了其生命周期为变量使用期间。静态局部变量是静态存储,存储在全局静态区,生命周期为从程序开始道结束。
  • 因此 static 这个说明符在不同的地方所起的作用是不同的。
  • 总结:全局变量、静态全局变量、静态局部变量采用静态存储方式,局部变量采用动态存储方式。

更详细文章看这里:
iOS的static修饰符

  1. 问题1:请简述iOS应用程序的五大内存分区及其主要用途。

答案:
iOS应用程序的内存分为以下五个主要分区:

1. **栈(Stack)**:- **用途**:用于存储局部变量、函数参数、返回地址等。栈内存是自动分配和释放的,主要用于函数调用和局部变量的管理。- **特点**:内存分配方式为LIFO(后进先出),存取速度快,空间相对较小。2. **堆(Heap)**:- **用途**:用于动态分配内存,存储需要在运行时分配和释放的对象和数据。堆内存由程序员手动管理,通过`malloc`、`free`、  `new`、`delete`等函数进行分配和释放。- **特点**:内存管理灵活,存储空间较大,但分配和释放速度相对较慢,容易产生内存碎片。3. **全局区/静态区(Global/Static)**:- **用途**:存储全局变量和静态变量。全局变量在程序启动时分配,在程序结束时释放;静态变量在第一次使用时分配,程序结束时释放。- **特点**:内存地址固定,生命周期贯穿程序运行的整个周期。4. **常量区(Constant)**:- **用途**:存储常量数据,例如字符串常量、数值常量等。常量区的内容在程序运行时不可修改。- **特点**:只读区域,数据在程序加载时初始化,生命周期贯穿程序运行的整个周期。5. **代码区(Code/Text)**:- **用途**:存储程序的可执行代码,包括函数体和编译后的指令。代码区在程序运行时是只读的,以防止意外修改。- **特点**:只读区域,存储的是编译后的机器指令,生命周期贯穿程序运行的整个周期。
  1. 问题2:为什么栈内存的分配和释放速度比堆内存快?

答案:
1. 分配方式:栈内存采用LIFO(后进先出)的分配方式,每次函数调用时,函数的局部变量、参数和返回地址会依次入栈,函数返回时,这些数据会依次出栈。分配和释放只需要移动栈指针,操作简单且高效。

2. **内存管理**:栈内存由系统自动管理,函数调用结束时,系统会自动释放栈内存,无需程序员手动管理。堆内存则需要程序员手动管理,通过`malloc`、`free`等函数进行分配和释放,管理复杂且容易产生内存碎片。3. **空间连续**:栈内存通常是连续的内存块,分配和释放时不需要进行复杂的内存碎片整理,而堆内存由于频繁的分配和释放,容易产生内存碎片,导致分配和释放速度变慢。
  1. 问题3:什么是内存碎片?如何在iOS开发中避免内存碎片?

答案:
内存碎片是指由于频繁的内存分配和释放,导致堆内存中出现大量无法使用的小块空闲内存,从而降低内存利用效率和分配速度。

在iOS开发中,避免内存碎片的方法包括

1. **使用自动内存管理**:iOS使用ARC(Automatic Reference Counting)来自动管理内存,减少手动分配和释放内存的操作,从而降低产生内存碎片的风险。2. **对象池技术**:对于频繁使用的对象,可以使用对象池(Object Pool)技术,将对象复用,而不是每次都创建新的对象,从而减少内存分配和释放的次数。3. **尽量避免频繁的内存分配和释放**:对于需要频繁分配和释放内存的操作,可以考虑优化算法或数据结构,减少内存分配和释放的频率。4. **使用合适的数据结构**:在设计数据结构时,尽量使用内存连续的数据结构,例如数组、链表等,避免过度使用需要频繁分配和释放内存的复杂数据结构。
  1. 问题4:全局区和静态区的内存是如何管理的?它们之间有什么区别?

答案:
全局区和静态区的内存管理方式如下:

- **全局区(Global)**:- 管理全局变量,即在程序的整个生命周期内都存在的变量。==这些变量在程序启动时分配内存==,在程序结束时释放内存。- 全局变量在定义时如果未显式初始化,系统会将其初始化为0。- **静态区(Static)**:- 管理静态变量,即在函数或类内部定义并带有`static`关键字的变量。==这些变量在第一次使用时分配内存==,在程序结束时释放内存。- 静态变量在第一次定义时如果未显式初始化,系统也会将其初始化为0。**区别**:
- **生命周期**:全局变量和静态变量的生命周期相似,都是在程序运行期间存在,但全局变量在程序启动时即被初始化,而静态变量在第一次使用时才被初始化。
- **作用域**:全局变量的作用域是整个程序,而静态变量的作用域仅限于其定义的函数或类内部。
  1. 问题5:代码区是只读的,这对程序安全性有什么影响?

答案:
代码区是只读的,这对程序的安全性有以下影响:

1. **防止代码篡改**:代码区的只读属性确保了程序在运行时,代码段不能被修改,从而防止恶意代码注入和篡改。这提高了程序的安全性,防止了病毒和恶意软件的攻击。2. **保护执行环境**:由于代码段是只读的,任何对代码区的写操作都会引发异常,从而防止意外或恶意修改代码指令,保证了程序的稳定运行。3. **避免缓冲区溢出攻击**:许多攻击技术,例如缓冲区溢出攻击,试图通过修改程序的执行路径来执行恶意代码。代码区的只读属性可以有效防止这些攻击,因为即使攻击者试图修改代码,系统也会检测到并阻止操作。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/388975.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

堆的实现-向上调整算法-向下调整算法-堆排序-TopK问题 C语言

一、堆的概念及结构 二、 向上调整算法 注意:循环条件不可写parent > 0 //向上调整算法 //child为下标 void adjustup(int* a, int child) {int parent (child - 1) / 2;while (child > 0){if (a[child] < a[parent]){swap(&a[child], &a[parent]);child pa…

CoderGuide

CoderGuide是一个针对同学们前后端求职面试的开源项目&#xff0c;作为一名互联网/IT从业人员&#xff0c;经常需要搜索一些书籍、面试题等资源&#xff0c;在这个过程中踩过很多坑、浪费过很多时间。欢迎大家 Watch、Star&#xff0c;供各位同学免费使用&#xff0c;永不收费&…

Spring框架 配置Gateway网关/spring cloud gateway 基础入门案例教程

文章目录 目录 文章目录 安装流程 小结 概要安装流程技术细节小结 概要 网关作为微服务集群唯一的对外入口,可以实现很多功能. 例如: 统一的解决跨域(一个ajax请求 origin域名和请求目标url中域名不同,ip不同,域名不同,端口不同,都会引发的问题)问题. 统一的身份认证.认证解…

C++ 关键字与库函数 学习总结

sizeof与strlen 含义 sizeof&#xff1a;是一个操作符&#xff0c;用于计算数据类型或变量的大小&#xff08;以字节为单位&#xff09;。在编译时求值strlen&#xff1a; 是一个函数&#xff0c;用于计算字符串的长度&#xff08;不包括终止符 \0&#xff09;。在运行时求值不…

考研数学|保100冲130暑假强化保姆级规划

只做这些的话还不够&#xff0c;还要加上真题、模拟题。而且必须确保自己完全掌握上面的内容。 只看30讲和做1000题考90分是比较有困难的。如果刷完知能行1000题&#xff0c;90分应该很稳。 张宇1000题是考研数学难度较大一些的题集&#xff0c;题目难&#xff0c;计算量大&a…

机器学习笔记 - RAFT 光流简读

一、光流 光流是图像序列中像素的表观运动。为了估计光流,场景中物体的移动必须具有相应的亮度位移。这意味着一个图像中移动的红球在下一个图像中应该具有相同的亮度和颜色,这使我们能够确定它以像素为单位移动了多少。下图显示了光流示例,其中一系列图像捕获了逆时针旋转的…

增加一个按钮,批量获取凭证号

create PROCEDURE Cux_Ar_ServiceLedger_Voucher_ProcOrgId Int ,result Int output AS BEGIN SET NOCOUNT ONDECLARE Date DATETIME IF OrgId 0 or OrgIdBEGIN RAISERROR(N获取当前组织ID失败&#xff01;, 16, 1) RETURNEND SET Date GETDATE()BEGIN TRANSACTION BEGIN…

微调(一)

微调有两种办法&#xff0c; 一是模型全部参数的微调&#xff0c;二是少量参数高效的微调。前者由于参数多&#xff0c;需要的GPU多&#xff0c;并且全参数微调可能把模型带偏&#xff0c;后者只需要微调少量参数&#xff0c;需要的GPU少&#xff0c;还可能达到不错的效果&…

秒懂Linux之自动化构建工具-make/Makefile

目录 一.前文摘要 二.make/Makefile 一.前文摘要 在学习自动化构建工具前我们先来补充一下动静态库的相关指令 动态库指令 gcc -o 文件&#xff08;重命名&#xff09; 源文件 静态库指令 gcc -o 文件&#xff08;重命名&#xff09; 源文件 -static 二.make/Makefile 怎么形…

MATLAB(14)预处理

一、前言 在MATLAB中进行插值拟合、主成分分析&#xff08;PCA&#xff09;和小波分析之前&#xff0c;通常需要对数据进行一些预处理。这些预处理步骤可能包括数据清洗、缺失值处理、标准化或归一化等。下面我将分别为这三种分析方法提供预处理模型的示例代码。 二、实现 1.…

校园点餐系统

1 项目介绍 1.1 摘要 在这个被海量信息淹没的数字化时代&#xff0c;互联网技术以惊人的速度迭代&#xff0c;信息的触角无处不在&#xff0c;社会的脉动随之加速。每一天&#xff0c;我们都被汹涌而至的数据浪潮包裹&#xff0c;生活在一个全方位的数字信息矩阵中。互联网的…

大模型微调实战项目总结(非常详细)零基础入门到精通,收藏这一篇就够了

写在前面 不知不觉之间&#xff0c;距开源ChatGLM-Finetuning项目已经过去了8个月。大模型也在飞速的发展&#xff0c;开源社区也是越来越活跃&#xff0c;开源模型越来越多。 中间更新过一次&#xff0c;将代码重构让大家更容易理解&#xff0c;本次更新主要增加ChatGLM3模型…

JavaScript (十)——JavaScript 比较 和 逻辑运算符

目录 JavaScript 比较 和 逻辑运算符 比较运算符 如何使用 逻辑运算符 条件运算符 语法 JavaScript 比较 和 逻辑运算符 比较和逻辑运算符用于测试 true 或者 false 比较运算符 比较运算符在逻辑语句中使用&#xff0c;以测定变量或值是否相等。 如何使用 可以在条件语…

【C++】模拟实现list

&#x1f984;个人主页:修修修也 &#x1f38f;所属专栏:数据结构 ⚙️操作环境:Visual Studio 2022 目录 一.了解项目及其功能 &#x1f4cc;了解list官方标准 了解模拟实现list &#x1f4cc;了解更底层的list实现 二.list迭代器和vector迭代器的异同 &#x1f4cc;迭代…

tomcat配置(java环境配置)

继昨天上线商城系统 [rootstaticserver eleme_web]# cd /usr/local/nginx/conf [rootstaticserver conf]# ls fastcgi.conf koi-utf nginx.conf scgi_params.default fastcgi.conf.default koi-win nginx.conf.bak uwsgi…

采用GDAL批量波段运算计算植被指数0基础教程

采用GDAL批量波段运算计算植被指数0基础教程 1. 引言 在传统的遥感数据处理方法中&#xff0c;通常使用ArcGis或ENVI软件进行波段运算。然而&#xff0c;这些软件在处理大量数据时往往效率低下。有没有一种方法可以批量进行波段运算&#xff0c;一下子计算几十个植被指数&…

计算word文件打印页数 VBA实现

目录 场景复现环境说明实现原理计算当前文件夹下所有word文件页数总和利用递归计算当前文件夹所有work文件页面数量几个BUG计算结果软件报价后话 场景复现 最近需要帮我弟打印高考资料&#xff0c;搜集完资料去网上打印&#xff0c;商家发出了这个计算页数的界面。我就好奇怎么…

如何把视频语音转文字?交给这4款工具就完事

这两天巴黎奥运会的盛大开幕&#xff0c;世界各地的记者们纷纷涌入这个体育盛事的现场&#xff0c;带着他们的镜头和麦克风&#xff0c;捕捉每一个激动人心的瞬间。 然而&#xff0c;随着采访的深入&#xff0c;如何快速准确地将这些珍贵的视频内容转化为文字记录&#xff0c;…

C语言 | Leetcode C语言题解之第309题买卖股票的最佳时机含冷冻期

题目&#xff1a; 题解&#xff1a; int maxProfit(int* prices, int pricesSize) {if (pricesSize 0) {return 0;}int f0 -prices[0];int f1 0;int f2 0;for (int i 1; i < pricesSize; i) {int newf0 fmax(f0, f2 - prices[i]);int newf1 f0 prices[i];int newf2…

Linux 和 Unix 的关系

Linux 和 Unix 的关系 2.2.1unix 是怎么来的 2.2.2Linux 是怎么来的 GNU计划的另一个目的是构建自由的软件文化&#xff0c;以支持以无条件自由软件和开放源码程序这种文化理念为核心的一整套系统&#xff0c;来推动软件在世界范围内的普及及发展。其中包括支持点&#xff08;推…