【iOS重学】浅谈iOS的包体积优化(二)
LinkMap分析可执行文件
LinkMap结构分析
基础信息
类表
段表
__TEXT:代码段
__DATA:数据段
后续符号表内容
代码节
方法名节
如何分析
查看第一列初始位置 比如0x1016FF830
然后看这个地址在【段表】中的哪个节里面 我们这里看到是在__objc_methodname
里面。
分析LinkMap的工具
__TEXT代码段迁移方案
Mach-O文件格式简介
可执行文件中Data
部分主要是以Segment(段)
和Section(节)
的方式来组织内容,使用命令xcrun size -lm
可执行文件路径 来详细查看Data
部分的结构和Segment/Section
的大小信息。
Data
有四个Segment
:__PAGEZERO
、__TEXT
、__DATA
、__LINKEDIT
,除了__PAGEZERO
、__LINKEDIT
,每个段中有多个Section
。
__PAGEZERO
:大小是4G,指的是可执行文件装载进内存后,__PAGEZERO
在内存中的大小,主要是用来捕捉NULL
指针的引用。__PAGEZERO
在可执行文件中并不占用Data
部分的空间。
__TEXT
、__DATA
:用于保存程序的代码指令和数据。
__LINKEDIT
:包含App启动需要的信息,比如代码签名符号表等。
__TEXT段迁移的原理
程序的过程主要有:预处理 - 编译 - 汇编 - 链接 四个主要阶段,完成之后就可以得到Mach-O可执行文件。
苹果只会扫描__TEXT
段,所以我们的想法是迁移__TEXT
段就可以避免上面的问题,这个方案在国内很大大型APP上其实也是比较常见的。
迁移__TEXT会减少下载大小的原理
苹果会对APP中的可执行文件进行DRM加密,然后将APP压缩成ipa文件再发布到App Store,加密对可执行文件大小本身影响比较小,它影响的是可执行文件的压缩效率,导致压缩后的ipa大小增加也就是下载大小增大。
使用命令【otool -l 可执行文件路径】来查看可执行文件是否被加密过:
苹果只会对可执行文件中的__TEXT
段加密,而不会对其他段加密。所以我们可以想到如果可以把__TEXT
段中的节移到其它段,就能减少苹果的加密范围,从而使压缩效率提升减少下载大小。
迁移__TEXT段具体方案
通过命令man ld
可以查看链接器参数,如下:
-rename _section
:orgSegment/orgSection
的名称修改为newSegment/newSection
-segprot
:为Segment
添加读、写、可执行权限等
在 Xcode - Build Settings - Other Linker Flags
中添加如下参数:
解释:
-Wl 是告诉Xcode 后面的参数是添加给链接器ld的,这些参数在链接阶段生效。
第一行参数:创建一个新的__TT_TEXT
段,并把__TEXT
,__text
移动到__TT_TEXT
,__text
。
第一行参数:创建一个新的__TT_TEXT
段,并把__TEXT
,__text
移动到__TT_TEXT
,__text
。
第二行参数:给__TT_TEXT
段添加可读和可执行权限。
使用命令xcrun size -lm 可执行文件路径
可以查看可执行文件的Data内容,如下:
通过上面的截图我们会发现:Data
里面会多了我们创建的__TT_TEXT
和__RODATA
两个Segment
,原本的__TEXT
和__DATA
的大小也会发生变化,至此,关于__TEXT
段具体如何迁移我们就简单的了解到这里了,本文也只是博主的一个学习笔记,如各位看官发现有任何问题请指正 在此感激不尽。