【iOS】虚拟内存 物理内存

发布时间:2026/11/3 4:54:16

【iOS】虚拟内存  物理内存 虚拟内存 物理内存早期的数据访问是直接通过物理地址访问的容易出现内存不够用、内存数据的安全问题。为了解决内存不够用的问题我们在进程和物理内存之间增加了一个中间层即虚拟内存主要用于解决当多个进程同时存在时对物理内存的管理。提高CPU的利用率使得多个进程可以同时、按需加载。这个虚拟内存本质上就是一张虚拟地址和物理地址对应关系的映射表每个进程都有一个独立的虚拟内存地址都是从0开始的大小为固定的4G每个虚拟内存又会划分为一个一个的页iOS中是16K其余4K每次加载都是按照页为单位加载的并且进程间无法相互访问。一个进程中只有部分功能是活跃的所以只需要将这些活跃的部分加入到物理内存中避免资源浪费当CPU需要访问数据时先访问虚拟内存然后通过虚拟内存去寻址查映射表的过程如果在访问时虚拟地址的内容未加载到物理内存就会发生缺页异常阻塞当前进程此时需要先将数据载入物理内存然后再寻址进行读取。按照上面的讲解虚拟内存的起始地址、大小都是固定的不安全所以苹果引入了ASLR技术iOS4.3即地址空间随机加载技术是一种针对缓冲区溢出的安全保护技术通过对堆、栈、共享库等线形布局的随机化增强安全性。但是由于ASLR的存在导致可执行文件和动态链接库在虚拟内存中的加载地址每次启动都不固定所以需要在编译时来修复镜像文件中的资源指针使指向正确的位置。所以正确的内存地址 ASLR地址 偏移值可执行文件不同操作系统其可执行文件的格式也不同系统内核读取文件到内存之后根据可执行文件的头签名判断二进制文件的格式然后决定使用什么方式加载和执行它通用二进制文件苹果中的通用二进制格式就是将多种架构的Mach-O文件打包然后根据自己CPU平台选择合适的Mach-O所以通用二进制格式也被称为胖二进制格式。可以同时存储多种架构的二进制指令使得CPU可以根据自身自动检测并选用合适的架构以最理想当方式进行读取。缺点是会占用大量的磁盘空间不相干的不会占用。Mach-O即Mach-Object文件格式的缩写用于可执行文件、动态库、目标代码的文件格式具有较强的扩展性以及更快的符号遍访问速度。Executable可执行文件Dylib动态链接库Bundle无法被链接的动态库只能在运行时使用dlopen加载image指的是executable、Dylib、Bundle的一种Framework包含dylib、资源文件和头文件的集合一个Mach-O文件主要分为三大部分header Mach-O头部存储Mach-O的cpu架构文件类型以及加载命令等信息Load Commands 加载命令描述了文件中数据的具体组织结构不同的数据类型使用不同的加载命令表示其中记录了很多信息例如动态链接器的位置、程序的入口、依赖库的信息代码的位置、符号表的位置之后等等Data数据数据中的每个段的数据都保存在这里与ELF文件中段的概念类似每个段都有一个或者多个部分放置了具体的数据与代码APP启动启动广义上的启动是点击图标到首页数据加载完成狭义上的启动是点击图标到启动图完全消失的第一帧启动的最佳时间是400ms以内因为从点击图标到显示launch screen到launch screen消失的时间间隔是400ms启动时间如果超过20s就会被系统杀掉。启动的计算方式起点进程创建时间终点第一个第一个CA::Transaction::commit()Core Animation提交事务的函数收集如修改frame、bounds、alpha、transform触发布局、动画刷新等不会立马刷新而是等到当前runloop快结束时系统统一调用启动分为冷启动和热启动冷启动系统中没有任何进程的缓存信息如重启手机后直接启动APP热启动从后台再次进入APP时就是热启动因为进程缓存还在杀掉App进程之后数据仍然存在时的启动我们所说的启动优化一般指的是冷启动情况下的启动主要分为两个部分pre-main阶段即main函数执行之前操作系统加载App可执行文件到内存执行的一系列加载链接等工作点击App - 系统创建进程 - 加载主Mach-O和dyld - dyld接管启动 - 加载依赖动态库 - rebase、bind符号修正 - objc runtime 注册类、方法、Category - 执行 load、constructor、C 静态初始化 - 调用 main() - UIApplicationMain() - 首屏渲染加载链接库从主文件的header获取到需要加载的所依赖动态库列表kernel加载时期而headre早就被内核映射过。dyld根据header中的记录找到每个依赖的dylib文件并判断是否是Mach-O类型,如果类型符合就找到代码签名并将其注册到内核中每个dylib包含若干个segmentdyld会对每个segment调用mmap()将文件映射到进程的虚拟内存中一个 dylib 本身可能依赖其他 dylib例如 UIKit 依赖 CoreFoundation。dyld 会递归解析依赖直到所有依赖树都被加载。系统 dylib 使用 dyld shared cache快速映射App 自带 dylib 需要从 App Bundle 打开和 mmap加载总数通常 100–400 个实际占用时间主要来自 App 自带和三方库。修正在加载所有的动态了链接库之后他们只是处在相互独立的状态需要将他们进行绑定即fix-ups。由于代码签名限制不能让一个dylib调用另一个dylib这时需要加很多中间层。现代code-gen被叫做动态PICposition independent code意味着代码可以被加载到间接的地址上当调用发生时code-gen实际上会在_DATA段上创建一个指向被调用者的指针然后加载指针并跳转过去所以dyld做的事就是修正指针和数据。这里fix-up包含两个部分rebease-binding启动优化pre-main阶段这个阶段主要就是dyld加载而dyld启动的第一步就是加载动态库由于缓存的存在加载系统的动态库速度较快而加载内嵌的动态库较慢所以我们可以通过减少动态库的数量实现提高启动效率。我们也可以通过合并动态库的方式但是不适合个人开发者我们也可以在rebase-binding阶段尝试优化对于OC开发来说主要的时间消耗在Class/Method的符号加载上我们可以通过下面方式实现优化减少__DAtA段中的指针数量Mach-O__DATA段中保存类、方法、selector、protocol、Category 指针。指针越多dyld rebase 和 bind 越耗时合并分类和功能相似的类减少无用的方法和类使用initialize代替load方法减少__attribute__((constructor))的使用constructor 在 main 前执行类似 load也会增加启动负担。不要创建线程创建线程本身会消耗 CPU、内存并增加调度开销。启动早期线程过多可能导致锁竞争、CPU抢占、首屏渲染策略main阶段延迟初始化不必要的UIViewController。能延迟的就延迟如一些SDK的初始化、界面的创建。不能延迟执行的尽量放在后台线程执行如数据的读取、日志发送等。启动优化总结pre-main阶段减少动态库数量合并不必要的自家动态库减少第三方动态 Framework。对无动态加载需求的库优先考虑静态链接。减少 main 前自动执行代码避免在 load、constructor、C 全局对象初始化中执行耗时任务。将初始化逻辑改为懒加载、dispatch_once 或 didFinishLaunching 后延迟执行。精简 Objective-C 元数据删除无用类、方法、Category、Protocol。合并过度碎片化的 Category减少 Runtime 扫描和方法合并成本。降低动态性Swift 中避免过度 objc 暴露和 NSObject 继承。能使用 final、struct 的地方尽量使用减少动态派发和 Runtime 元数据。控制 Method Swizzling避免启动期大量 swizzle。必须 swizzle 的逻辑应尽量轻量或延迟到对应子系统启用时执行。main阶段轻量化首屏rootViewController 保持轻量。延迟创建非首屏控制器、大型视图树和复杂模块。避免主线程重任务不在主线程做同步 I/O、网络请求、大 JSON 解析、图片解码、数据库操作。非首屏任务放后台队列并在首帧后分批执行。SDK 延迟初始化只保留启动必要 SDK。支付、分享、地图、广告、IM 等非首屏能力按需初始化。优化布局Auto Layout 约束保持完整闭环。减少首帧前反复 updateConstraints 和 layoutSubviews。降低首屏视图层级和布局复杂度。优化首屏资源图片尺寸与展示尺寸匹配。减少首屏大字体、大图片、大配置文件。首屏必要资源本地化、小体积化避免远程依赖。启动流程总结从用户点击App图标开始系统先创建进程按照info.plist做基础配置校验建立沙箱然后使用launchScreen.storyboard显示启动画面然后进入dyld阶段将可执行文件和依赖的动态库从共享缓存中加载进来执行ASLR符号binding随后运行时初始化OC注册类与分类执行C/C的全局构造器和Objc的load方法。进入main之后调用UIApplicationMain创建UIApplication启动主线程RunLoopiOS13以后通常走UIScene在scene:willConnectTo:方法中配置window和根式图控制器首个控制器会依次触发loadView、viewDidLoad、viewWillAppear动画结束之后调用viewDidAppear,然后系统移除启动图呈现首帧动画。
延伸阅读

更多相关文章

2026/10/25 9:09:00

STM32驱动压电蜂鸣器实现高音量报警系统设计

1. 项目背景与核心需求在工业控制、安防系统和智能家居等领域,可靠的声音警报系统是不可或缺的基础组件。传统蜂鸣器存在音量不足、音质单薄、环境适应性差等问题,而基于压电陶瓷技术的EPT-14A4005P蜂鸣器配合STM32F334R8微控制器的解决方案,…

2026/11/2 11:30:50

跨平台引流实战:从浏览器到应用商店的智能跳转方案解析

1. 跨平台引流的技术挑战与解决方案当用户通过社交媒体或网页分享链接访问推广页面时,如何精准引导用户下载或打开App?这个问题看似简单,实则涉及复杂的设备识别和跳转逻辑。不同操作系统、不同品牌设备、不同浏览器环境,都需要针…

2026/11/3 4:50:00

配电网风光储选址定容系统与改进粒子群算法应用

1. 项目概述:配电网风光储选址定容系统核心功能这个系统本质上解决的是新能源接入配电网时的规划难题。当我们在配电网中接入风电、光伏和储能设备时,最头疼的问题就是"装在哪里"和"装多大"——选址不对可能导致电压越限、线路过载&…

2026/11/3 4:50:00

消化专病数据库建设方案:2端+1链架构与联邦学习落地实践

简介:面向消化疾病临床研究者、中医药循证研究团队及医疗数据管理人员,这份PDF聚焦优势病种专病数据库的建设路径与共享难题,可作为了解行业现状与平台架构的参考材料。文档围绕中国中医药循证医学中心消化疾病协同创新联盟展开,梳…

2026/11/3 4:50:00

MySQL执行计划深度解析:从EXPLAIN读懂优化器决策

1. 项目概述:这不是“调优指南”,而是一份真实踩坑后写下的SQL优化手记“MYSQL SQL优化一 学习笔记”——看到这个标题,你大概率会下意识划走:又是一篇堆砌EXPLAIN、索引类型、B树原理的教科书式复述?但我想先说清楚&a…

2026/11/3 4:50:00

编程语言保留字高效记忆工具与技术解析

1. 项目背景与核心价值编程语言中的保留字就像交通规则里的红绿灯——看似简单却至关重要。作为从业十余年的老码农,我见过太多新手因为记混保留字而引发的"血案":从简单的语法报错到诡异的逻辑漏洞,甚至有人因为误用class关键字导…

2026/11/3 4:50:00

基于MCP协议与Docker的LLM Agent记忆回溯机制hindsight设计与实现

1. 从“hindsight”说起:为什么我们需要给Agent装上“后视镜”“hindsight”这个词,直译过来就是“后见之明”,或者更通俗一点——“事后诸葛亮”。但在LLM Agent的开发语境里,它指的是一套让智能体能够回顾、检索并利用过往交互记…

2026/11/3 4:45:00

基于CPS-1848的RapidIO 48口交换板设计与联调指南

简介:《CPS 1848 用户手册》是面向网络硬件工程师、驱动开发者与RapidIO系统设计人员的芯片技术文档,针对IDT CPS-1848中央包交换芯片,帮助读者理解其功能、接口与配置方法。压缩包共1个PDF文件,大小约9.05MB,便于离线…

2026/11/2 6:08:01

面向复杂光照与角度的宠物面部识别鲁棒性增强策略

在智慧养宠时代,基于视觉的宠物身份识别技术正逐步从实验室走向家庭应用。然而,与配合度高的人类不同,宠物是典型的“非合作生物识别对象”——它们不会主动配合摄像头调整姿态,更无法控制光照环境。实际应用中,我们常…

2026/11/2 6:39:12

SSM电子书店源码全解析:结构、原理、部署与排错实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/11/3 1:04:48

STM32实战:基于MAX14431数字隔离器的SPI隔离通信方案

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/11/3 1:04:48

工业SPI隔离通信设计:MAX14431BAEE+与STM32L4A6RG实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/11/3 1:04:48

STM32+NRF24L01无线抢答器:硬件设计、通信协议与低功耗实现

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/11/2 6:08:01

面向复杂光照与角度的宠物面部识别鲁棒性增强策略

在智慧养宠时代,基于视觉的宠物身份识别技术正逐步从实验室走向家庭应用。然而,与配合度高的人类不同,宠物是典型的“非合作生物识别对象”——它们不会主动配合摄像头调整姿态,更无法控制光照环境。实际应用中,我们常…

2026/11/2 6:39:12

SSM电子书店源码全解析:结构、原理、部署与排错实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑