【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);
}
可以看出,堆内存分配是 不连续的
栈和堆的区别联系
- 各自的优缺点?
- 栈:由编译器自动分配并释放,速度较快,不会产生内存碎片。优点是快速高效,缺点是有限制,数据不灵活。
- 堆: 由程序员分配和释放,速度比较慢,而且容易产生内存碎片,不过用起来最方便。优点是灵活方便,数据适应面广泛,但是效率有一定降低
- 申请后的系统如何响应?
- 栈:存储每一个函数在执行的时候都会向操作系统索要资源,栈区就是函数运行时的内存,栈区中的变量由编译器负责分配和释放,内存随着函数的运行分配,随着函数的结束而释放,由系统自动完成。只要栈的剩余空间大于所申请空间,系统将为程序提供内存,否则将报异常提示栈溢出。
- 堆:操作系统有一个记录空闲内存地址的链表。当系统收到程序的申请时,会遍历该链表,寻找第一个空间大于所申请空间的堆结点,然后将该结点从空间结点链表中删除,并将该结点的空间分配给程序。由于找到的堆结点的大小不一定正好等于申请的大小,系统会自动的将多余的那部分重新放入空闲链表中。
- 申请大小的限制?
- 栈: 栈是向低地址扩展的数据结构,是一块连续的内存的区域。栈顶的地址和栈的最大容量是系统预先规定好的,栈的大小是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。
常量区
- 该区是编译时分配的内存空间,在程序运行过程中,此内存中的数据一直存在,程序结束后由系统释放。
- 存放常量: 整形、字符型、浮点、字符串等
- 常量区是编译时分配的内存空间,在程序结束后由系统释放,主要存放:
- 已经使用了的,且没有指向的字符串常量
- 字符串常量因为可能在程序中被多次使用,所以在程序运行之前,就回提前分配内存。
代码区
- 该区时编译时分配的内存空间,在程序运行过程中,此内存中的数据一直存在,程序结束后由系统释放
- 程序运行时的代码会被编译成二进制,存进内存的代码区域
面试题
- 讲一下static关键字的各种情况以及作用
答:
- 对于全局变量来说,static 改变了其作用域。普通全局变量是所有文件都可以用。静态全局变量是只有当前文件可以用。
- 对于局部变量来说,static改变了其存储方式从而改变了生命周期。普通局部变量是动态存储,动态存储决定了其生命周期为变量使用期间。静态局部变量是静态存储,存储在全局静态区,生命周期为从程序开始道结束。
- 因此 static 这个说明符在不同的地方所起的作用是不同的。
- 总结:全局变量、静态全局变量、静态局部变量采用静态存储方式,局部变量采用动态存储方式。
更详细文章看这里:
iOS的static修饰符
- 问题1:请简述iOS应用程序的五大内存分区及其主要用途。
答案:
iOS应用程序的内存分为以下五个主要分区:
1. **栈(Stack)**:- **用途**:用于存储局部变量、函数参数、返回地址等。栈内存是自动分配和释放的,主要用于函数调用和局部变量的管理。- **特点**:内存分配方式为LIFO(后进先出),存取速度快,空间相对较小。2. **堆(Heap)**:- **用途**:用于动态分配内存,存储需要在运行时分配和释放的对象和数据。堆内存由程序员手动管理,通过`malloc`、`free`、 `new`、`delete`等函数进行分配和释放。- **特点**:内存管理灵活,存储空间较大,但分配和释放速度相对较慢,容易产生内存碎片。3. **全局区/静态区(Global/Static)**:- **用途**:存储全局变量和静态变量。全局变量在程序启动时分配,在程序结束时释放;静态变量在第一次使用时分配,程序结束时释放。- **特点**:内存地址固定,生命周期贯穿程序运行的整个周期。4. **常量区(Constant)**:- **用途**:存储常量数据,例如字符串常量、数值常量等。常量区的内容在程序运行时不可修改。- **特点**:只读区域,数据在程序加载时初始化,生命周期贯穿程序运行的整个周期。5. **代码区(Code/Text)**:- **用途**:存储程序的可执行代码,包括函数体和编译后的指令。代码区在程序运行时是只读的,以防止意外修改。- **特点**:只读区域,存储的是编译后的机器指令,生命周期贯穿程序运行的整个周期。
- 问题2:为什么栈内存的分配和释放速度比堆内存快?
答案:
1. 分配方式:栈内存采用LIFO(后进先出)的分配方式,每次函数调用时,函数的局部变量、参数和返回地址会依次入栈,函数返回时,这些数据会依次出栈。分配和释放只需要移动栈指针,操作简单且高效。
2. **内存管理**:栈内存由系统自动管理,函数调用结束时,系统会自动释放栈内存,无需程序员手动管理。堆内存则需要程序员手动管理,通过`malloc`、`free`等函数进行分配和释放,管理复杂且容易产生内存碎片。3. **空间连续**:栈内存通常是连续的内存块,分配和释放时不需要进行复杂的内存碎片整理,而堆内存由于频繁的分配和释放,容易产生内存碎片,导致分配和释放速度变慢。
- 问题3:什么是内存碎片?如何在iOS开发中避免内存碎片?
答案:
内存碎片是指由于频繁的内存分配和释放,导致堆内存中出现大量无法使用的小块空闲内存,从而降低内存利用效率和分配速度。
在iOS开发中,避免内存碎片的方法包括:
1. **使用自动内存管理**:iOS使用ARC(Automatic Reference Counting)来自动管理内存,减少手动分配和释放内存的操作,从而降低产生内存碎片的风险。2. **对象池技术**:对于频繁使用的对象,可以使用对象池(Object Pool)技术,将对象复用,而不是每次都创建新的对象,从而减少内存分配和释放的次数。3. **尽量避免频繁的内存分配和释放**:对于需要频繁分配和释放内存的操作,可以考虑优化算法或数据结构,减少内存分配和释放的频率。4. **使用合适的数据结构**:在设计数据结构时,尽量使用内存连续的数据结构,例如数组、链表等,避免过度使用需要频繁分配和释放内存的复杂数据结构。
- 问题4:全局区和静态区的内存是如何管理的?它们之间有什么区别?
答案:
全局区和静态区的内存管理方式如下:
- **全局区(Global)**:- 管理全局变量,即在程序的整个生命周期内都存在的变量。==这些变量在程序启动时分配内存==,在程序结束时释放内存。- 全局变量在定义时如果未显式初始化,系统会将其初始化为0。- **静态区(Static)**:- 管理静态变量,即在函数或类内部定义并带有`static`关键字的变量。==这些变量在第一次使用时分配内存==,在程序结束时释放内存。- 静态变量在第一次定义时如果未显式初始化,系统也会将其初始化为0。**区别**:
- **生命周期**:全局变量和静态变量的生命周期相似,都是在程序运行期间存在,但全局变量在程序启动时即被初始化,而静态变量在第一次使用时才被初始化。
- **作用域**:全局变量的作用域是整个程序,而静态变量的作用域仅限于其定义的函数或类内部。
- 问题5:代码区是只读的,这对程序安全性有什么影响?
答案:
代码区是只读的,这对程序的安全性有以下影响:
1. **防止代码篡改**:代码区的只读属性确保了程序在运行时,代码段不能被修改,从而防止恶意代码注入和篡改。这提高了程序的安全性,防止了病毒和恶意软件的攻击。2. **保护执行环境**:由于代码段是只读的,任何对代码区的写操作都会引发异常,从而防止意外或恶意修改代码指令,保证了程序的稳定运行。3. **避免缓冲区溢出攻击**:许多攻击技术,例如缓冲区溢出攻击,试图通过修改程序的执行路径来执行恶意代码。代码区的只读属性可以有效防止这些攻击,因为即使攻击者试图修改代码,系统也会检测到并阻止操作。
相关文章:

【iOS】iOS内存五大分区
iOS内存五大分区 总揽 iOS中,内存主要分为五大区域:栈区,堆区,全局区/静态区,常量区和代码区。总览图如下。 这个图我觉得更好记,因为下面是低地址,上面是高地址,是比较符合日常…...

【项目实战】—— 高并发内存池
文章目录 什么是高并发内存池?项目介绍一、项目背景二、项目目标三、核心组件四、关键技术五、应用场景六、项目优势 什么是高并发内存池? 高并发内存池是一种专门设计用于高并发环境下的内存管理机制。它的原型是Google的一个开源项目tcmallocÿ…...

二叉搜索树的第 k 大的节点
题目描述 给定一棵二叉搜索树,请找出其中第 k 大的节点。 解题基本知识 二叉搜索树(Binary Search Tree)又名二叉查找树、二叉排序树。它是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子…...
利用langchain 做大模型 Few-shot Learning 提示,包括固定和向量相似的动态样本筛选
文章目录 few-shotFixed Examples 固定样本Dynamic few-shot prompting 动态样本提示辅助参考资料 few-shot 相比大模型微调,在有些情况下,我们更想使用 Few-shot Learning 通过给模型喂相关样本示例,让模型能够提升相应任务的能力。 固定样…...

基于python的百度迁徙迁入、迁出数据分析(五)
终于在第五篇文章我们进入了这个系列的正题:数据分析 这里我选择上海2024年5月1日——5月5日的迁入、迁出数据作为分析的基础,首先选择节假日的数据作为分析的原因呢,主要是节假日人们出行目的比较单一(出游、探亲)&a…...
SpringBoot 如何处理跨域请求
SpringBoot 处理跨域请求,通常是通过配置全局的 CORS(跨源资源共享)策略来实现的。CORS 是一种机制,它使用额外的 HTTP 头部来告诉浏览器,让运行在一个 origin (domain) 上的 web 应用被准许访问来自不同源服务器上的指…...

大数据技术基础编程、实验和案例----大数据课程综合实验案例
一、实验目的 (1)熟悉Linux系统、MySQL、Hadoop、HBase、Hive、Sqoop、R、Eclipse等系统和软件的安装和使用; (2)了解大数据处理的基本流程; (3)熟悉数据预处理方法; (4)熟悉在不同类型数据库之…...

微信小程序-获取手机号:HttpClientErrorException: 412 Precondition Failed: [no body]
问题: 412 异常就是你的请求参数获取请求头与服务器的不符,缺少请求体! 我的问题: 我这里获取微信手机号的时候突然给我报错142,但是代码用的是原来的代码,换了一个框架就噶了! 排查问题&am…...

大数据核心概念与技术架构简介
大数据基本概念 大数据是指无法在一定时间范围内用常规软件工具进行捕捉、管理和处理的数据集合,是具有更强的决策力、洞察发现力和流程优化能力的海量、高增长率和多样化的信息资产。 大数据特征: 数据量大:一般以P(1000个TB&a…...
快排 谁在中间
原题 Whos in the Middle FJ is surveying his herd to find the most average cow. He wants to know how much milk this median cow gives: half of the cows give as much or more than the median; half give as much or less. FJ正在调查他的牛群,以找到最…...
ORA-00911: invalid character
场景: 调用接口查询oracle的数据库数据时报错ORA-00911: invalid character,但是sql语句没有问题放在navicat控制台中运行也没有问题,但是代码中跑就会报无效字符集 分析: 代码中Oracle的语法解析器比较严格,比如句…...

Pytorch实现线性回归Linear Regression
借助 PyTorch 实现深度神经网络 - 线性回归 - 第 2 周 | Coursera 线性回归预测 用PyTorch实现线性回归模块 创建自定义模块(内含一个线性回归) 训练线性回归模型 对于线性回归,特定类型的噪声是高斯噪声 平均损失均方误差函数:…...

十八次(虚拟主机与vue项目、samba磁盘映射、nfs共享)
1、虚拟主机搭建环境准备 将原有的nginx.conf文件备份 [rootserver ~]# cp /usr/local/nginx/conf/nginx.conf /usr/local/nginx/conf/nginx.conf.bak[rootserver ~]# grep -Ev "#|^$" /usr/local/nginx/conf/nginx.conf[rootserver ~]# grep -Ev "#|^$"…...

P1340 兽径管理 题解|最小生成树
题目大意 洛谷中链接 推荐文章:并查集入门 原文 约翰农场的牛群希望能够在 N N N 个草地之间任意移动。草地的编号由 1 1 1 到 N N N。草地之间有树林隔开。牛群希望能够选择草地间的路径,使牛群能够从任一 片草地移动到任一片其它草地。 牛群可在…...
Python,Maskrcnn训练,cannot import name ‘saving‘ from ‘keras.engine‘ ,等问题集合
Python版本3.9,tensorflow2.11.0,keras2.11.0 问题一、module keras.engine has no attribute Layer Traceback (most recent call last):File "C:\Users\Administrator\Desktop\20240801\代码\test.py", line 16, in <module>from mrc…...

Linux常用工具
文章目录 tar打包命令详解unzip命令:解压zip文件vim操作详解netstat详解df命令详解ps命令详解find命令详解 tar打包命令详解 tar命令做打包操作 当 tar 命令用于打包操作时,该命令的基本格式为: tar [选项] 源文件或目录此命令常用的选项及…...
AI未来的发展如何
AI(人工智能)的发展前景非常广阔,随着技术的不断进步和应用场景的不断拓展,AI将在多个领域发挥重要作用。以下是对AI发展前景的详细分析: 一、技术突破与创新 生成式AI的兴起:以ChatGPT为代表的生成式AI技…...

若依替换首页上的logo
...
sed的使用示例
场景:使用sed将多个空格变成单空格,再使用cut来切分得到需要的结果 得到后面这个文件名: ls ./ drwxr-x— 2 root root 6 Jul 18 9:00 7b40f1412d83c1524af7977593607f15 drwxr-x— 2 root root 6 Jul 18 14:00 50af29cef2c65a9d28905a3ce831bcb7 drwxr-x— 2 root root 6 Jul…...
学历不是障碍:大专生如何成功进入软件测试行业
摘要: 在当今技术驱动的职场环境中,软件测试已成为一个关键的职业领域。尽管许多人认为高学历是进入这一行业的先决条件,但实际上,大专学历的学生同样有机会在软件测试领域取得成功。本文将探讨大专生如何通过技能提升、实践经验和…...
浅谈 React Hooks
React Hooks 是 React 16.8 引入的一组 API,用于在函数组件中使用 state 和其他 React 特性(例如生命周期方法、context 等)。Hooks 通过简洁的函数接口,解决了状态与 UI 的高度解耦,通过函数式编程范式实现更灵活 Rea…...
java_网络服务相关_gateway_nacos_feign区别联系
1. spring-cloud-starter-gateway 作用:作为微服务架构的网关,统一入口,处理所有外部请求。 核心能力: 路由转发(基于路径、服务名等)过滤器(鉴权、限流、日志、Header 处理)支持负…...

关于nvm与node.js
1 安装nvm 安装过程中手动修改 nvm的安装路径, 以及修改 通过nvm安装node后正在使用的node的存放目录【这句话可能难以理解,但接着往下看你就了然了】 2 修改nvm中settings.txt文件配置 nvm安装成功后,通常在该文件中会出现以下配置&…...

el-switch文字内置
el-switch文字内置 效果 vue <div style"color:#ffffff;font-size:14px;float:left;margin-bottom:5px;margin-right:5px;">自动加载</div> <el-switch v-model"value" active-color"#3E99FB" inactive-color"#DCDFE6"…...

如何在看板中有效管理突发紧急任务
在看板中有效管理突发紧急任务需要:设立专门的紧急任务通道、重新调整任务优先级、保持适度的WIP(Work-in-Progress)弹性、优化任务处理流程、提高团队应对突发情况的敏捷性。其中,设立专门的紧急任务通道尤为重要,这能…...
【python异步多线程】异步多线程爬虫代码示例
claude生成的python多线程、异步代码示例,模拟20个网页的爬取,每个网页假设要0.5-2秒完成。 代码 Python多线程爬虫教程 核心概念 多线程:允许程序同时执行多个任务,提高IO密集型任务(如网络请求)的效率…...

c#开发AI模型对话
AI模型 前面已经介绍了一般AI模型本地部署,直接调用现成的模型数据。这里主要讲述讲接口集成到我们自己的程序中使用方式。 微软提供了ML.NET来开发和使用AI模型,但是目前国内可能使用不多,至少实践例子很少看见。开发训练模型就不介绍了&am…...
高防服务器能够抵御哪些网络攻击呢?
高防服务器作为一种有着高度防御能力的服务器,可以帮助网站应对分布式拒绝服务攻击,有效识别和清理一些恶意的网络流量,为用户提供安全且稳定的网络环境,那么,高防服务器一般都可以抵御哪些网络攻击呢?下面…...

人工智能(大型语言模型 LLMs)对不同学科的影响以及由此产生的新学习方式
今天是关于AI如何在教学中增强学生的学习体验,我把重要信息标红了。人文学科的价值被低估了 ⬇️ 转型与必要性 人工智能正在深刻地改变教育,这并非炒作,而是已经发生的巨大变革。教育机构和教育者不能忽视它,试图简单地禁止学生使…...
【JavaSE】多线程基础学习笔记
多线程基础 -线程相关概念 程序(Program) 是为完成特定任务、用某种语言编写的一组指令的集合简单的说:就是我们写的代码 进程 进程是指运行中的程序,比如我们使用QQ,就启动了一个进程,操作系统就会为该进程分配内存…...