美文网首页
包体积优化那些事——符号表、动态库

包体积优化那些事——符号表、动态库

作者: sea777777 | 来源:发表于2020-07-07 10:17 被阅读0次

符号表优化

尽可能的隐藏符号表:
如果我们写了10个方法,但是并不是全都让外部来调用,就需要把这部分符号隐藏

//暴露符号表 __attribute__((visibility("default"))) 

//隐藏符号 
//不会放到Dynamic Symbol Table 里,所以不会被dyld找到 __attribute__((visibility("hidden")))
image.png
参考一下fishhook的图:
image.png

由上图可见:_la_symbol ptr 会指向 indirect symbol table , indirect symbol table(只存储了symbol table的索引) 指向symbol table,symbol table(包含string table的指针 和 type、desc等) 指向了string table。

那么我们最终优化的就是 _la_symbol ptr ,也就是说我们设置 了__attribute__((visibility("hidden"))),符号表就不会被加载到 _la_symbol里,进而减少符号的体积

xcode提供了一个全局的开关,用来设置符号的默认可见性:
image.png

我们可以设置为NO,隐藏符号表,然后对需要暴露的方法设置:__attribute__((visibility("default")))




动态库和静态库的选择

在静态链接(ld)阶段,动态库会把整个lib复制进mach-o中,这显然不太符合包体积优化的需求。

但是静态库在静态链接阶段,仅把用到的文件link到mach-o中,这一点和动态库区别很大,符合包体积优化需求。

对于静态库,尽量不要使用-Objc (加载所有object c文件)或 all_load(加载所有文件),显然这不太合适,可用-force_load替代。

另外,不选用动态库的另外一个原因是:动态库单独享有一份__TEXT段,而静态库也享有一份_TEXT段。

如果动态库、静态库有些类、方法都是相同的,会在静态库、动态库各有一份__TEXT段,造成不必要的冗余。

下面我写了个动态库:(dylib有单独__TEXT,所以不会和静态库的__TEXT产生符号冲突)
image.png


关于xcode配置的一些选项

1、(Levels选项内)Generate Debug Symbols 设置为NO,这个配置选项应该会让你减去小半的体积。注意这个如果设置成NO就不会在断点处停下,

这个选项不会生成DSYM文件,但是不建议这么做,因为DSYM文件是解析crash的重要途径,如:bugly就需要上传DSYM文件。

image.png
2、Strip Linked Product:If enabled, the linked product of the build will be stripped(剪裁、拖掉)of symbols when performing deployment postprocessing.

当设置成YES , 会剪裁掉不需要的符号,但前提是把Deployment Postprocessing 设置为 YES 。

image.png
3、Strip Style:
  • All Symbols - 完全剪裁符号,剪裁效果:强
  • Non-Global Symbols - 剪裁掉非全局符号(global symbols供外部符号链接时候使用),剪裁效果:中
  • Debugging Symbols - 剪裁掉 debugging 的符号,发布app之后可以选择此项,剪裁效果:弱

注:静态库不要选 All Symbols,因为ld在进行link的时候会用到符号来进行链接。

image.png
4、Debug Information Level:当设置成Line tables only , 就只会生成方法名,行号等,但不会包含变量、方法参数等上下文

设置后可以看到包体积的确有少量缩减;

image.png
5、Dead Code Stripping ,删除 dead code 符号,项目中无用文件较多时,可以减少体积。
image.png
6、Debug Information Format ,debug模式下设置为DWARF即可,release模式下设置为DWARF with dSYM File即可

解释一下DWARF:每个文件被编译成.o 后缀的中间文件,这个文件会包含调试信息,也就是DWARF (debugging with attributed record formats)

补充一点:我们即使生成了dsym文件,发布到 appstore 之后,ipa 也不会包含这个dsym文件,这个文件只给开发者来解析crash日志使用。

下面我们用file命令查看dsym、dwarf文件格式:
% file test.app.dSYM
test.app.dSYM: directory   //dsym实际是个文件夹

//我们继续查看 dsym 文件夹里面内容,有一个test文件,他就是dwarf格式的文件 
% file test 
test: Mach-O 64-bit dSYM companion file arm64 //可以看到这个dwarf文件是一个mach-o文件 ,并且是64位的,支持 arm64架构
再看一下这个dsym文件的格式——没有了__TEXT 和 __DATA段,而多了__DWARF段:
image.png image.png
7、编译器优化级别

Build Settings->Optimization Level有几个编译优化选项,release版应该选择Fastest, Smalllest[-Os],这个选项会开启那些不增加代码大小的全部优化,并让可执行文件尽可能小。




arm 架构优化

舍弃架构 armv7、armv7s、i386、x86,保留arm64即可,因为从5s往后都是arm64的

  • armv7 用于支持4s和4,4s是2011年11月正式上线,虽然还有小部分人在使用,但是追求包体大小的完全可以舍弃了。
  • armv7s 用于iPhone5,基本也可以删除了
  • i386 是模拟器架构,也可以删除
  • x86 是mac架构,可以删除



检测各个模块占用大小

要想知道优化哪些库,那么我们要先生成link map,然后对每个库进行分析

xcode要开启Write Link Map File,然后指定路径即可

https://github.com/zgzczzw/LinkMapParser(解析格式)

下面是解析完的情况:我们可以针对某些特大的包进行符号表剪裁、资源压缩、arm架构剪裁等

================================================================================
                            linkmap.txt各模块体积汇总        
================================================================================
Creating Result File : BaseLinkMapResult.txt
libavcodec.a                                      15.09M
WeexSDK                                           4.95M
opencv2                                           3.64M
React                                             3.04M
libavformat.a                                     1.49M
SwiftProtobuf                                     1.24M
libmp4v2.a                                        1.23M
libx264.a                                         1.18M
libPaymentControl.a                               1.17M
libavfilter.a                                     1.14M
linker synthesized                                1.12M
Samyou                                            1.04M
总体积:                                           179.32M
================================================================================



图片处理

用 LSUnusedResource 这个软件查找项目中没有用到的图片,然后删除

https://github.com/tinymind/LSUnusedResources/raw/master/Release/LSUnusedResources.app.zip

用 ImageOptim 压缩图片的大小,如果是png图片,可以针对不需要透明的图片剪裁掉他的alpha通道。 ImageOptim是支持这一项的

对于PNG图片来说,文件可能更大,但是解码会相对较快,而Xcode会把 PNG图片进行解码优化之后引入工程。

对于JPEG图片来说,他体积更小,但是解码要消耗更长的时间,因为JPEG解压算法比基于zip的PNG算法更加复杂。




查找冗余的文件

Fui : https://github.com/dblock/fui

注意这里:有些用不到的文件,其中包含+load方法,这种应该注意,因为只要文件参与编译,+load方法就会被调用,不要轻易删除

相关文章

  • 包体积优化那些事——符号表、动态库

    符号表优化 尽可能的隐藏符号表:如果我们写了10个方法,但是并不是全都让外部来调用,就需要把这部分符号隐藏 参考一...

  • APK包优化比较佳实践

    包体积的优化是件繁琐且长久的事,下面是本人的优化经验,对包体积有要求的产品可以参考。 首先介绍几个好用的第三方工具...

  • 包体积优化

    为什么需要优化包体积 下载转化率,包体积增加不利于用户下载 推广成本,包体积增大推广成本也会加大 应用市场限制 包...

  • 包体积优化

    1.删除无用图片资源https://github.com/tinymind/LSUnusedResources2....

  • 包体积优化

    Aandroid的安装包APK文件本身就是个压缩文件,把后缀改成.zip,解压后,能看到安装包的内容包括 要减少安...

  • 包体积优化

    https://juejin.cn/post/7116089040264232967[https://juejin...

  • Mac上提取assets.car图片

    我们在进行包体积优化时,会去查看分析ipa包,因为看到这篇文章iOS 优化IPA包体积(今日头条)[https:/...

  • 2018-06-17

    基于rollup的组件库打包体积优化 背景 前段时间对公司内部的组件库(类似element-ui)做了打包体积优化...

  • 包体积瘦身

    包体积是什么 包体积优化前,先要明白包体积是什么,在app store上看到的体积又是什么。在app store里...

  • iOS性能优化

    1、参考文章 TableView优化 FPS监测 //启动优化、内存优化、卡顿优化、线程优化、电量优化、包体积...

网友评论

      本文标题:包体积优化那些事——符号表、动态库

      本文链接:https://www.haomeiwen.com/subject/njigqktx.html