【iOS】内存五大分区
目录
- 堆(Heap)是什么
- 五大分区
- 栈区
- 堆区
- 全局/静态区
- 常量区(即.rodata)
- 代码区(.text)
- 函数栈
- 堆和栈的区别和联系
- 图解
OC语言是C语言的超集,所以先了解C语言的内存模型的内存管理会有很大帮助。C语言的内存模型分为5个区:栈区、堆区、全局/静态区、常量区、代码区
一般情况下程序存放在ROM(只读内存,比如硬盘)或Flash中,运行时需要拷到RAM(随机存储器RAM)中执行,RAM会分别存储不同的信息,如下图所示:

RAM(random access memory):运行内存,CPU可以直接访问,读写速度快,但是不能掉电存储。它又分为:
- 动态DRAM,速度慢一点,需要定期的刷新(充电),常说的内存条就是指它,价格会稍低一点,手机中的运行内存也是指它
- 静态SRAM,速度快,我们常说的一级缓存,二级缓存就是指它,价格高一点
ROM(read only memory):存储性内存,可以掉电存储,eg:SD卡、Flash(机械磁盘也可以简单的理解为ROM)。用的多的:NandFlash(空间大,便宜),还有NorFlash(直接运行程序,读取速度快)
|_|
由于RAM类型不具备掉电存储能力(即一停止供电数据全没了,从新上电后全是乱码,所以需要初始化),所以app程序一般存放于ROM中。RAM的访问速度要远高于ROM,价格也要高
由于RAM不能掉电存储,所以我们的APP程序,刷机包,下载的文件等等,都是在ROM里面存储的手机里面使用的ROM基本都是NandFlash,CPU是不能直接访问的,而是需要文件系统/驱动程序(嵌入式中的EMC)将其读到RAM里CPU才可以访问
下面先了解一下堆是怎么存放和操作数据的
堆(Heap)是什么
堆是计算机科学中一类特殊的数据结构的统称。在队列中,调度程序反复提取队列中第一个作业并运行,因为实际情况中某些时间较短的任务将等待很长时间才能结束,或者某些不短小,但具有重要性的作业,同样应当具有优先权。堆即为解决此类问题设计的一种数据结构
|_|
堆(Heap)又被为优先队列(priority queue)。尽管名为优先队列,但堆并不是队列。在堆中,我们不是按照元素进入队列的先后顺序取出元素的,而是按照元素的优先级取出元素
这就好像候机的时候,无论谁先到达候机厅,总是头等舱的乘客先登机,然后是商务舱的乘客,最后是经济舱的乘客。每个乘客都有头等舱、商务舱、经济舱三种个键值(key)中的一个。头等舱->商务舱->经济舱依次享有从高到低的优先级
总的来说,堆是一种数据结构,数据的插入和删除是根据优先级定的,他有几个特性:
- 任意节点的优先级
≥它的子节点 - 每个节点值都
≤它的子节点 - 主要操作是插入和删除最小元素(元素值本身为优先级键值,小元素享有高优先级)
举个例子,就像叠罗汉,体重大(优先级低、值大)的站在最下面,体重小的站在最上面(优先级高,值小)。 为了让堆稳固,我们每次都让最上面的参与者退出堆,也就是每次取出优先级最高的元素

五大分区
栈区
-
栈是
一块连续的内存区域从高地址向低地址进行存储,遵循先进后出(FILO)原则 -
栈区由操作系统在运行时自动分配,声明的变量过了作用域范围后内存便会自动释放,静态分配由编译器完成(自动变量
auto),动态分配由alloc函数完成 -
函数内部定义的
局部变量、方法参数(方法中的默认参数:self、_cmd),都存放在栈区 -
优缺点
- 优点:栈是由系统自动分配并释放的,不会产生内存碎片,所以
快速高效(栈使用的是一级缓存, 他们通常都是被调用时处于存储空间中,调用完毕立即释放) - 缺点:查看官方文档,栈的内存大小有限制,数据不灵活,iOS
主线程栈大小是1MB,其他线程是512KB,MAC只有8M
- 优点:栈是由系统自动分配并释放的,不会产生内存碎片,所以
-
栈的地址空间在iOS中是以
0x7/0x16开头- (void)testStack {int a = 7777777;NSLog(@"a == %p, size == %lu", &a, sizeof(a));NSLog(@"方法参数self:%p", &self);NSLog(@"方法参数cmd:%p", &_cmd); }
堆区
-
堆是不连续的内存区域从从低地址向高地址进行存储,类似于链表结构(便于增删,不便于查询),遵循先进先出(FIFO)原则
-
开发者需要关注变量的生命周期,如果不及时释放,会造成内存泄漏,只有等程序结束时由操作系统统一回收
-
存放的是OC中运行时使用
alloc、new创建的对象,C/C++中使用malloc、calloc以及realloc分配的空间,需要free释放 -
优缺点
- 优点:获得空间灵活,分配内存较大
- 缺点:需手动管理,频繁的
new/delete势必会造成内存空间的不连续性,速度慢、容易产生内存碎片(堆则是存放在二级缓存中,生命周期由虚拟机的垃圾回收算法来决定,并不是一旦成为孤儿对象就能被回收)
-
堆的地址空间在iOS中是以
0x6开头- (void)testHeap {NSObject* object1 = [[NSObject alloc] init];NSObject* object2 = [[NSObject alloc] init];NSLog(@"object1 = %@", object1);NSLog(@"object2 = %@", object2); }
全局/静态区
-
该区是编译时分配的内存空间,在程序运行过程中,此内存中的数据一直存在,全局变量和静态变量的存储是放在一起的,初始化的全局变量和静态变量存放在一块区域,未初始化的全局变量和静态变量在相邻的另一块区域,程序结束后由系统释放
-
未初始化的全局变量和静态变量,即BSS区(
.bss) -
已初始化的全局变量和静态变量,即数据区(
.data) -
全局区的空间地址在iOS中一般以
0x1开头int bssA; static double dataB = 7.0;- (void)testExOrSt {NSLog(@"bssA == %p", &bssA);NSLog(@"dataB == %p", &dataB); }
常量区(即.rodata)
- 该区是编译时分配的内存空间,在程序运行过程中,此内存中的数据一直存在,程序结束后由系统释放
- 存放的是
整型、字符型、浮点、常量字符串等常量 - 常量只读
代码区(.text)
- 该区是编译时分配的内存空间,在程序运行过程中,此内存中的数据一直存在,程序结束后由系统释放
程序运行时的代码会被编译成二进制,存进内存的代码区域- 只读,代码段需要防止在运行时被非法修改,所以只允许读取操作,而不允许写入操作
函数栈
函数栈:又称为栈区,在内存中从高地址往底地址分配,与堆区相对。
栈帧:指函数(运行中且未完成)占用的一块独立的连续内存区域
应用中新创建的每个线程都有专用的栈空间,栈可以在线程期间自由使用。而线程中有千千万万的函数调用,这些函数共享进程的这个栈空间。每个函数所使用的栈空间是一个栈帧,所有的栈帧就组成了这个线程完整的栈
函数调用是发生在栈上的,每个函数的相关信息(例如局部变量、调用记录等)都存储在一个栈帧中,每执行一次函数调用,就会生成一个与其相关的栈帧,然后将其栈帧压入函数栈,而当函数执行结束,则将此函数对应的栈帧出栈并释放掉
以下是ARM的栈帧布局方式:

main stack frame为调用函数的栈帧func1 stack frame为当前函数(被调用者)的栈帧栈底在高地址,栈向下增长。FP就是栈基址,它指向函数的栈帧起始地址SP则是函数的栈指针,它指向栈顶的位置ARM压栈的顺序很是规矩(也比较容易被黑客攻破么),依次为当前函数指针PC、返回指针LR、栈指针SP、栈基址FP、传入参数个数及指针、本地变量和临时变量。如果函数准备调用另一个函数,跳转之前临时变量区先要保存另一个函数的参数- ARM也可以用
栈基址和栈指针明确标示栈帧的位置,栈指针SP一直移动,ARM的特点是,两个栈空间内的地址(SP+FP)前面,必然有两个代码地址(PC+LR)明确标示着调用函数位置内的某个地址
堆栈溢出
一般情况下应用程序是不需要考虑堆和栈的大小的,但是事实上堆和栈都不是无上限的,过多的递归会导致栈溢出,过多的alloc变量会导致堆溢出
所以预防堆栈溢出的方法:
- 避免
层次过深的递归调用 不要使用过多的局部变量,控制局部变量的大小避免分配占用空间太大的对象,并及时释放- 实在不行,适当的情景下
调用系统API修改线程的堆栈大小
堆和栈的区别和联系
1. 各自的优缺点?
- 栈:由编译器自动分配并释放,速度较快,不会产生内存碎片。优点是快速高效,缺点时有限制,数据不灵活
- 堆:由程序员分配和释放,速度比较慢,而且容易产生内存碎片,不过用起来最方便。优点是灵活方便,数据适应面广泛,但是效率有一定降低
2. 申请后的系统如何响应?
- 栈:存储每一个函数在执行的时候都会向操作系统索要资源,栈区就是函数运行时的内存,栈区中的变量由编译器负责分配和释放,内存随着函数的运行分配,随着函数的结束而释放,由系统自动完成。只要栈的剩余空间大于所申请空间,系统将为程序提供内存,否则将报异常提示栈溢出。
- 堆:操作系统有一个记录空闲内存地址的链表。当系统收到程序的申请时,会遍历该链表,寻找第一个空间大于所申请空间的堆结点,然后将该结点从空闲结点链表中删除,并将该结点的空间分配给程序。由于找到的堆结点的大小不一定正好等于申请的大小,系统会自动的将多余的那部分重新放入空闲链表中
3. 申请大小的限制?
- 栈:栈是向低地址扩展的数据结构,是一块连续的内存的区域。是栈顶的地址和栈的最大容量是系统预先规定好的,栈的大小是2M(也有的说是1M,总之是一个编译时就确定的常数 ) ,如果申请的空间超过栈的剩余空间时,将提示overflow。因此,能从栈获得的空间较小
- 堆:堆是向高地址扩展的数据结构,是不连续的内存区域。这是由于系统是用链表来存储的空闲内存地址的,自然是不连续的,而链表的遍历方向是由低地址向高地址。堆的大小受限于计算机系统中有效的虚拟内存。由此可见,堆获得的空间比较灵活,也比较大
图解

相关文章:
【iOS】内存五大分区
目录 堆(Heap)是什么五大分区栈区堆区全局/静态区常量区(即.rodata)代码区(.text) 函数栈堆和栈的区别和联系图解 OC语言是C语言的超集,所以先了解C语言的内存模型的内存管理会有很大帮助。C语言…...
Jupyter Notebook: 是一个强大的交互式计算
文章目录 引言Jupyter Notebook的原理基础使用安装与启动单元格(Cell)操作快捷键 高级使用魔术命令Markdown支持可视化版本控制 优缺点优点缺点 官网链接结论 引言 Jupyter Notebook是一个强大的交互式计算环境,特别适用于数据科学、机器学习…...
【C#学习笔记】变量、变量类型
在C#中,变量是存储数据的容器,每个变量都有其特定的数据类型,这决定了变量可以存储的数据类型和大小。以下是关于C#中变量的由浅入深的详细解释,并附带代码示例和解释: 基础概念 定义: 变量是存储数据的容…...
题解:T480718 eating
eating 题目背景 从前有个荣光的王国,小 A 是里面的国王,今天他要赐予他的子民以仓廪。 题目描述 在一条街上有 n n n 个饭店。小 A 站在这条街的最左端。 第 i i i 个饭店离这条街最左端的距离是 a i a_i ai,它所售卖的菜品的美味…...
MATLAB中matfile用法
目录 语法 说明 示例 创建 MAT 文件对象 启用对 MAT 文件的写访问权限 加载整个变量 将整个变量保存至现有 MAT 文件 加载和保存部分变量 确定变量大小 参数说明 局限性 提示 matfile的功能是访问和更改 MAT 文件中的变量,而不必将文件加载到内存中。 …...
Spring之Spring Bean的生命周期
Spring Bean的生命周期 通过BeanDefinition获取bean的定义信息调用构造函数实例化beanBean的依赖注入处理Aware接口(BeanNameAware、BeanFactoryAware、ApplicationContextAware)Bean的后置处理器BeanPostProcessor-前置初始化方法(Initiali…...
OSINT 开源情报中的地理定位方法
了解 OSINT 中的地理定位技术、如何获取地理位置数据以及如何将地理定位用于各种调查场景。 OSINT 中的地理定位基础知识 OSINT 代表开源情报,指的是从免费公共来源合法收集的有关个人或组织的信息。这包括在互联网上以及书籍、公共图书馆报告、报纸文章、新闻稿、…...
Java面试题系列 - 第17天
Java中的代理模式与动态代理 背景说明:代理模式是一种结构型设计模式,用于在客户端和目标对象之间提供一个代理或占位符。在Java中,动态代理技术允许在运行时创建代理对象,这在AOP(面向切面编程)和RPC&…...
开发环境搭建
1、Ubuntu 系统设置 root 用户密码 新安装的ubuntu没有设置 root 用户密码,打开终端,输入 sudo passwd root 执行命令后依次输入密码 2、虚拟机设置网络适配器 3、Ubuntu 系统下搭建 FTP 服务器 sudo apt-get update sudo apt-get install vsftpd sudo apt-get install vim…...
【NLP】关于参数do_sample的解释
在自然语言处理(NLP)领域,特别是在使用神经网络模型进行文本生成时,do_sample是一个常见的参数,用于控制模型生成文本的方式。具体来说,do_sample参数决定模型是否采用随机采样(sampling&#x…...
Vbox虚拟机+Ubuntu motest测试drm
1. 效果演示 大家做学习drm的时候,没有硬件测试平台不方便测试,这里给大家演示下如何基于Vbox虚拟机Ubuntu测试drm的一些功能,先看下演示视频。 没有光标测试: demo_vwmfgx_test_drm 带有光标测试: demo_vwmfgx_drm_with_cursor 可以看到,有…...
ArcGIS Pro SDK (九)几何 15 转换
ArcGIS Pro SDK (九)几何 15 转换 文章目录 ArcGIS Pro SDK (九)几何 15 转换1 创建地理转换2 创建复合地理变换3 创建投影转换4 创建高压基准变换5 创建复合高压基准变换6 决定转换7 地图点 - 地理坐标字符串转换 环境࿱…...
Spring IOC DI --- 认识IOC DI
T04BF 👋专栏: 算法|JAVA|MySQL|C语言 🫵 今天你敲代码了吗 文章目录 认识Ioc & DIIoc是什么?DI是什么? 认识Ioc & DI 我们知道,Spring 是一个开源框架,让我们的开发更加简单.但是更加具体来说,实际上Spring 是包含了众多工具方法的Ioc容器 …...
常用的python程序汇总——入门级
只用于记录最近的一些日常程序。 目录 前言 一、文件和目录管理 1.读取文件结构 读取所有文件夹和文件 读取到N级子文件夹和文件 只读取到N级子文件夹 2.遍历文件并处理(复制、删除) 说明: 二、数据分析和处理 三、数据可视化 四、…...
被问到MQ消息已丢失,该如何处理?
在分布式系统中,消息中间件(如 RabbitMQ、RocketMQ、Kafka、Pulsar 等)扮演着关键角色,用于解耦生产者和消费者,并确保数据传输的可靠性和顺序性。尽管我们通常会采取多种措施来防止消息丢失,如消息持久化、…...
open3d:ransac分割多个平面(源码)
1、背景介绍 随机采样一致性算法(RANSAC Random Sample Consensus)是一种迭代的参数估计算法,主要用于从包含大量噪声数据的样本中估计模型参数。其核心思想是通过随机采样和模型验证来找到数据中最符合模型假设的点。因此,只要事先给定要提取的参数模型,即可从点云中分割…...
Github 2024-07-17 开源项目日报 Top10
根据Github Trendings的统计,今日(2024-07-17统计)共有10个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量非开发语言项目3Python项目3Rust项目2TypeScript项目2MDX项目1项目化学习 创建周期:2538 天协议类型:MIT LicenseStar数量:161973 个Fork数量…...
vue3中Composition API写法 <script setup>标签中哪些可以不用导入即可使用?
在 Vue 3 中使用 <script setup> 时,确实有一些全局的 API 和宏可以直接使用,而不需要显式地从 vue 包中导入它们。这是因为 <script setup> 是专门为了提供更简洁的组件编写方式而设计的,它内部利用了编译时的语法糖。 以下是在…...
Facebook Dating:社交平台的约会新体验
随着社交媒体的普及和技术的发展,传统的社交方式正在经历革新,尤其是在约会这个领域。Facebook作为全球领先的社交平台,推出了Facebook Dating,旨在为用户提供一个全新的约会体验。本文将探讨Facebook Dating如何重新定义社交平台…...
【系统架构设计 每日一问】五 搜索型业务,采用MySQL+ES,如何保证数据一致性
将数据从MySQL同步到Elasticsearch(ES)中并保证一致性是一个常见的需求,特别是在需要快速全文搜索和分析功能的应用中。以下是一些常见的方法和实践来确保数据一致性: 1. 使用双写策略 描述:在应用程序层面ÿ…...
7.4.分块查找
一.分块查找的算法思想: 1.实例: 以上述图片的顺序表为例, 该顺序表的数据元素从整体来看是乱序的,但如果把这些数据元素分成一块一块的小区间, 第一个区间[0,1]索引上的数据元素都是小于等于10的, 第二…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院挂号小程序
一、开发准备 环境搭建: 安装DevEco Studio 3.0或更高版本配置HarmonyOS SDK申请开发者账号 项目创建: File > New > Create Project > Application (选择"Empty Ability") 二、核心功能实现 1. 医院科室展示 /…...
让回归模型不再被异常值“带跑偏“,MSE和Cauchy损失函数在噪声数据环境下的实战对比
在机器学习的回归分析中,损失函数的选择对模型性能具有决定性影响。均方误差(MSE)作为经典的损失函数,在处理干净数据时表现优异,但在面对包含异常值的噪声数据时,其对大误差的二次惩罚机制往往导致模型参数…...
视觉slam十四讲实践部分记录——ch2、ch3
ch2 一、使用g++编译.cpp为可执行文件并运行(P30) g++ helloSLAM.cpp ./a.out运行 二、使用cmake编译 mkdir build cd build cmake .. makeCMakeCache.txt 文件仍然指向旧的目录。这表明在源代码目录中可能还存在旧的 CMakeCache.txt 文件,或者在构建过程中仍然引用了旧的路…...
CRMEB 中 PHP 短信扩展开发:涵盖一号通、阿里云、腾讯云、创蓝
目前已有一号通短信、阿里云短信、腾讯云短信扩展 扩展入口文件 文件目录 crmeb\services\sms\Sms.php 默认驱动类型为:一号通 namespace crmeb\services\sms;use crmeb\basic\BaseManager; use crmeb\services\AccessTokenServeService; use crmeb\services\sms\…...
Razor编程中@Html的方法使用大全
文章目录 1. 基础HTML辅助方法1.1 Html.ActionLink()1.2 Html.RouteLink()1.3 Html.Display() / Html.DisplayFor()1.4 Html.Editor() / Html.EditorFor()1.5 Html.Label() / Html.LabelFor()1.6 Html.TextBox() / Html.TextBoxFor() 2. 表单相关辅助方法2.1 Html.BeginForm() …...
深度剖析 DeepSeek 开源模型部署与应用:策略、权衡与未来走向
在人工智能技术呈指数级发展的当下,大模型已然成为推动各行业变革的核心驱动力。DeepSeek 开源模型以其卓越的性能和灵活的开源特性,吸引了众多企业与开发者的目光。如何高效且合理地部署与运用 DeepSeek 模型,成为释放其巨大潜力的关键所在&…...
【实施指南】Android客户端HTTPS双向认证实施指南
🔐 一、所需准备材料 证书文件(6类核心文件) 类型 格式 作用 Android端要求 CA根证书 .crt/.pem 验证服务器/客户端证书合法性 需预置到Android信任库 服务器证书 .crt 服务器身份证明 客户端需持有以验证服务器 客户端证书 .crt 客户端身份…...
【记录坑点问题】IDEA运行:maven-resources-production:XX: OOM: Java heap space
问题:IDEA出现maven-resources-production:operation-service: java.lang.OutOfMemoryError: Java heap space 解决方案:将编译的堆内存增加一点 位置:设置setting-》构建菜单build-》编译器Complier...
C++ Saucer 编写Windows桌面应用
文章目录 一、背景二、Saucer 简介核心特性典型应用场景 三、生成自己的项目四、以Win32项目方式构建Win32项目禁用最大化按钮 五、总结 一、背景 使用Saucer框架,开发Windows桌面应用,把一个html页面作为GUI设计放到Saucer里,隐藏掉运行时弹…...
