iOS内存相关知识还有二进制重排的介绍

原创文章
声明:作者声明此文章为原创,未经作者同意,请勿转载,若转载,务必注明本站出处,本平台保留追究侵权法律责任的权利。
全栈老韩
全栈工程师,擅长iOS App开发、前端(vue、react、nuxt、小程序&Taro)开发、Flutter、React Native、后端(midwayjs、golang、express、koa)开发、docker容器、seo优化等。

二进制重排

  • 大型项目用的比较多
  1. iOS内存
  • 物理内存:没有办法直接访问物理内存,即内存条的真实地址

  • 虚拟内存:LLDB调试如打印内存地址或者真实的内存地址,都是虚拟内存

  • 早期的内存都是物理内存,内存不够时,给出内存不够的弹窗

缺点: (所以引入虚拟内存)

  • 软件一次性加载到内存中,对内存消耗太大
  • 外挂,检索内存,修改数据,如修改金币数量,跨进程访问数据
  • 每一个进程,都有对应的映射表,映射到物理内存
  1. 访问虚拟内存
  2. 虚拟内存映射到物理内存
  3. 访问数据,映射,然后cpu,通过硬件MMU,和操作系统去从虚拟内存到物理内存.
  4. 一个进程对应于一个虚拟页表
  5. 一个虚拟页表有好多段
  6. 进程并不是整个的被载入到内存,只有用户数据正在活跃的数据载入。
  7. 分段载入时,段的大小,涉及到分页,有哪些页正在活跃,就载入到内存
  8. 不可以字节为单位,否则映射表就会比较大,应以页为单位
  9. 页的地址+偏移地址,找到某一个数据
  10. 页的大小,MacOS,Linux,页是4K的大小,iOS一页是16K.
  11. 环境变量PAGESIZE,可以看出页的多少,通过终端.
  12. 以上也是虚拟内存产生的原因
  • 用户点开一个app,是一页一页加载

  • 进程访问数据的时候,访问的是虚拟页表,如果这个数据通过页表查询,不在物理内存上,那么产生阻塞,阻塞当前进程,叫缺页异常。

  • 由操作系统触发。

  • 然后到磁盘上查找这一页,加载到物理内存,加载完毕,进程继续。访问进程数据,cpu通过mmu进行地址翻译,得知这一页数据已经加载,有映射关系,通过虚拟内存找到物理内存真实数据,再加载。

  • 虚拟内存势必消耗时间,毫秒级别

  • 但是速度会很快,用户基本感知不到缺页异常,可以几乎忽略不计

  • 概念:页面置换

  • 用户点开某一页,加载到物理内存时,如果物理内存满了,将物理内存中不活跃的页,进行替换.

问题:什么样的时刻,缺页异常会同时大量的出现?

app启动的时候:数据加载、方法调用,一定会出现耗时

  • 技术层面
    降低缺页异常次数 -> 启动优化

  • 优化方案?

  • 合并动态库是一个动态库加载时间减少的方案

  • 不加载不必要的页

  • Xcode工程的build settings中有一个设置项:Write Link Map file

  • 编译工程得到product后,可以show in finder去找到LinkMap-normal-arm64.txt文件

  • 文件里面有Symbols的执行顺序,这个顺序跟compile source files的添加顺序有关。

  • 而单个文件中的方法执行顺序,跟代码书写顺序相同。

  • 假设:

  • 如果启动时,有500个缺页异常,因为启动时刻需要调用的方法分别分布在了这500页数据里面。

  • 但是这500页里的数据里,不全都是启动时需要调用的方法.

  • 如果,让app链接的顺序,按照启动调用顺序来进行排列,那么启动时必要的方法都会优先执行

暂无评论,快来发表第一条评论吧