iOS五大内存分区

我们知道任何一个程序在运行的时候实际是运行在内存中的,这个内存也就是我们通常所说的主存,也叫运行内存,也叫RAM(Random Access Memory),是可以直接与CPU进行交换数据的内部存储器。内存读取速度很快,所以作为操作系统运行程序的区域。不同的分区保存不同的值,值可以为指针,可以为对象,可以为二进制代码,可以为数字等,每个分区有自己的功能,它们一起协作为系统提供更好的任务划分。

在这里插入图片描述

堆区(heap)

由程序员管理(分配释放),堆区是由开发者“手动管理”或者程序结束时由系统全部回收,是一种树状的数据结构,一般用于存储由malloc、new等方式创建的对象。在iOS开发中,大多数关于内存管理方面的问题也多出自此:多是一些开发者没有及时回收内存,或者内存溢出以及泄漏等问题。

栈区(stack)

由编译器管理(分配释放),存放函数参数值、局部变量的值(函数中的基本数据类型)栈区的操作方式类似于数据结构中的栈(先进后出)。

全局区(静态区)

由编译器管理(分配释放),程序结束后由系统释放。存放全局变量和静态变量。有两块区域组成全局区(静态区),一块是存放未初始化的全局变量和静态变量,另一块是初始化完成的全局变量和静态变量,这两块区域是相邻的。

文字常量区

由编译器管理(分配释放),主要存储基本数据类型的值,以及常量,同样是进程结束后由系统回收。

程序代码区

存放函数的二进制代码,如果需要执行就加载到该区域中。

特例

这里应该再注意以下几个特例。

1.字符串类型
多个直接声明的相同字符串在内存中只占用一份内存,例如:

     NSLog(@"hello1: %p", @"Hello");NSLog(@"hello2: %p", @"Hello");

打印出来的结果是:

     hello1: 0x100001168hello2: 0x100001168

这个变量的地址是在常量区中存储,虽然声明的是两个字符串,看似应该开辟两端内存,但通过打印可以看出实际上是同一块内存,这是可以理解的,因为这是同一个固定的字符串,在编译期就确定了的,不会更改,是一个不可变量,因此引用同一份内存并没有什么问题,如果需要在此字符串上进行修改也是另外开辟一段内存。

其实上面的字符串就是__NSCFConstantString,这种字符串存在于常量区,通常的不太短的字符串是__NSCFString,存在于堆区。还有一种是将内容存于地址,叫做标签指针。详情可看:NSString的三种类型管理方式

  1. block类型

block声明的时候是在栈中的,但赋值给变量的时候会复制到堆中。

     //声明一个blockNSLog(@"block in stack: %p", ^(){});//将一个block赋值给一个变量id block = ^(){};NSLog(@"block in heap: %p", block);

示例代码:
在这里插入图片描述

打印结果:

     a=3, *p=3a=3, *p=1

这是关于block作用的一个非常典型的例子,可以很明确地看到block对外部变量的作用。两个方法中,都声明了一个int类型的a,赋值为1,接着声明一个int指针p指向a。在第一个方法中,直接调用了一个block,由于block还没有被赋值,所以这时block还没有复制到堆中,所以对于a来说也没有发生复制,与p指向的为同一内容。所以经过两次加1后,两者都为3;而对于第二个方法,将这个block赋值给一个临时变量,此时根据之前我们所说的内容,发生了复制,__block修饰的a也复制为一份新的内容,但p依然指向之前的内容,此时p的指向和a已经不是同一内容了,所以∗p依然为1,而a经过两次加1后,变为3。

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

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

相关文章

天池大赛中药说明书实体识别挑战冠军方案开源(二)部署运行实战 附详细操作说明

目录 Introduction 导言环境搭建环境 Github地址项目目录说明使用步骤下载预训练模型更改部分代码模型训练参数设置BERT-CRF模型训练BERT-SPAN模型训练BERT-MRC模型训练 运行训练预测复赛 test 文件 (上述模型训练完成后) 参考资料其它资料下载 Introduc…

2023最新 Navicat 16.2.3 安装和学习试用连接Redis教程详解

🌷🍁 博主 libin9iOak带您 Go to New World.✨🍁 🦄 个人主页——libin9iOak的博客🎐 🐳 《面试题大全》 文章图文并茂🦕生动形象🦖简单易学!欢迎大家来踩踩~&#x1f33…

react-flow基础使用及dagre库的使用

前言 最近项目中需要用到拓扑图的展示,最开始选用的是antv的拓扑图组件。antv组件虽然此很方便,但是在布局的时候总是会有莫名其妙的bug,然后自己也想法去解决(看前辈经验、官方issue),最后还是不能解决。…

【RuoYi-Cloud-Plus】学习笔记 09 - Sentinel(四)熔断降级知识整理

文章目录 前言参考目录版本说明学习笔记1、包结构2、DegradeSlot3、DegradeRule4、DegradeRuleManager5、CircuitBreaker5.1 CircuitBreaker.State6、AbstractCircuitBreaker6.1、AbstractCircuitBreaker#fromCloseToOpen6.2、AbstractCircuitBreaker#fromHalfOpenToOpen6.3、A…

Edge浏览器无法展示Stable Diffusion Control Net插件

Edge浏览器无法展示Stable Diffusion Control Net插件 最近在学习Stable Diffusion,需要使用到Control Net插件,结果通过各种方式安装成功插件后,浏览器页面没有展示ControlNet相关页面,最终换到Chorme浏览器后正常,猜…

安全测试方法介绍(上)静态源代码审查

软件开发完成之后,我们需要进行安全验证,验证我们的软件是不是符合安全要求。软件安全测试主要有以下几个方面:确定软件的安全特性实现是否与预期设计一致的过程;有关验证软件安全等级和识别潜在安全缺陷的过程;查找软…

云服务器下WordPress发送邮件的设置

WordPress的邮件功能很强大,可以实现用户密码以往后自助恢复等问题。 WordPress默认是使用php发邮件的,php需要配置好smtp(端口25)服务器及密码。这种方式不直观,因此一般都用smtp插件,常用的插件是WP Mai…

6.2.6 网络基本服务----电子邮件系统(E-mail)

6.2.6 网络基本服务----电子邮件系统(E-mail) 电子邮件系统是因特网上使用的最多且最受用户欢迎的一种应用 电子邮件系统包括用户代理和邮件服务器,提供收发邮件、邮件传送服务,邮件被传送到收信人邮件服务器的收信人信箱中&…

使用STM32实现 蓝牙插座

硬件介绍 蓝牙模块HC-01,其实之前就用过,使用起来非常简单 继电器模块, (VCC 3.3V)当左侧IN输入低电平时,右侧的ON 和 COM会导通,左上的绿灯会亮,此处充当插座的角色 项目需求 通过蓝牙的串口发送open打开…

8086变址寄存器和字符串拷贝程序学习

在此文用到了si和di寄存器; 8086汇编语言显示带颜色的字符串程序学习 - 使用emu8086_bcbobo21cn的博客-CSDN博客 下面单独来学习si和di寄存器; SI和DI是8086CPU中和BX功能相近的寄存器; 区别:SI和DI不能够分成两个8位寄存器来使用&#xff…

docker安装的mysql更改全文检索分词配置

这里使用的是mysql8.0,默认使用ngram分词 这里是已经将文件从容器中挂载出来了,没挂载出来要去容器内部更改my.cnf文件并重启mysql容器 步骤 一、查看mysql的分词大小 show variables like %token%;ngram_token_size这里默认是2我已经改为1了 这个值…