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

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

作者: 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方法就会被调用,不要轻易删除

    相关文章

      网友评论

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

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