静态库和动态库的区别这里不做过多的介绍,只贴下大家对他们的观点
对比一下静态和动态库的优缺点
这是很常见的认知,理论上也没有什么问题,但是这里对包大小的影响,角度上跟实际项目中却不一样。
比如SDWebImage打成动态库大小为648kb
而静态库大小为1.2M
为啥说角度不一样呢,目前这个大小是站在单个库上面讨论的。 就单个而言静态库比动态库大多了。
而实际上我们是要使用一堆库并导出一个ipa的,我们要从对整体的影响上来看可能是另一个结果。
为啥是另一个结果呢,我们慢慢实验。
首先先看测试工程下各组件静态库下大小
这些静态库总大小都超过10M了,而最后出了多少货呢?
最后发现出的货在2M左右(不是App Store大小,仅做参考)
这里大家肯定都很理解,也没觉得奇怪在哪里。
是的,镇改静态库最终链接到主可执行文件却变小了,这个大家肯定都是遇到过,知道估算包大小是无法使用静态库的大小来算的。
那么为啥变小了呢,猜测可能有几个原因
1、静态库里面含有一些符号信息便于定位,(为啥这样说,别人给你的库带有dSYM吗? 但是我们依然能定位到行数) 在链接完符号信息剥离出去,只留下真正可执行的二进制。
2、头文件等一些文件没了,可以忽略不计
3、静态库中的是中间文件,链接过程优化了静态库里面的.o文件
下面是使用hopper打开静态库的提示,跟已经编译好的动态库完全不一样。
那么静态库链接后对包大小没有显示的大小那么大,为啥会有人拿单个库做比较呢。
如果还不相信,那么我们来看看动态库对最终的包大小有哪些影响。
同样的项目,把依赖的第做罩三方库全部改成动态库。
大小如下:
从这些数据来看,确实每一个都小很多,但是大家忽略了一点,静态库参与链接到主可执行文件会变小很多,而动态库却不会,它是以什么形式存在呢。
打开app内部,查看里面的目录,大家可以看到熟悉的Frameworks目录
这个目录里面都是存放一些动态库,动态库是copy进去的,当然会做一些签名、去除头文件等 *** 作,编译器几乎不会对动态库做过多的事,所以一些朋友可能会遇到打包的时候App Store提示不能包括i386,x86_64等模拟器的架构,因为它对动态库没做剔除工作。
那么这些copy过去的库大小有什么变化,答案是几乎没什么变化,可能因为去除一些没用的东西小了一丢丢。
Frameworks目录总大小也在4.9M,和上面的数据差不多。
而打出的包在5M左右。
所以可以看到最终动态库打出的ipa是大于静态库的。
使用hopper打开动态库我们可以看到AFNetworking和SDWebImage的动态库里面有关一些基础的使用方法存在重复Name,却不同的Address,比如这个dispatch_once。
那么我们可以猜出每个动态库里面会有一些其他的调用信息,而因为动态库是独立的,具有隔离型,相互不影响。
静态库大却在最终的链接优化掉,而动态库却完完全全copy过去,那存在一些重复的信息怎么办?
这个最终也是造成包御胡判变大的一个因素,当然也可能存在其他原因。
而动态库还存在动态链接影响性能的问题(当然有些人会延迟链接也是一种办法)
动态库也不能真正的共享,
动态库依赖静态库这种关系复杂起来也难倒了好一些人。
所以我们一直鼓励尽可能的使用静态库。 当然也不是说动态库不使用,有时候解决一些依赖问题,也会用的到,但是尽量少用,我们项目因为全部改成静态库整整小了20M左右。
所以结论是:静态库单个虽大,但是链接到主可执行文件中就会小很多,并且加快了启动时间。
以上均测试出来的数据,如果问题请指出, 本文结论仅供参考。
[《深入理解计算机系统》-读后感]介绍:本书从程序员的视角详细阐述计算机系统的本质概念,并展示这些概念如何实实在在地影响应用程序的正确性、性能和实用性,《深入理解计算机系统》-读后感。全书共12章,主要内容包括信息的表示和处理、程序的机器级表示、处理器体系结构、优化程序性能、存储器层次结构、链接、异常控制流、虚拟存储器、系统级I/O、网络编程、并发编程等。书中提供大量的例子和练习,并给出部分答案,有助于读者加深对正文所述概念和知识的理解。
本书的最大优点是为程序员描述计算机系统的实现细节,帮助罩伍其在大脑中构造一个层次型的计算机系统,从最底层的数据在内存中的表示到流水线指令的构成,到虚拟存储器,到编译系统,到动态加载库,到最后的用户态应用。通过掌握程序是如何映射到系统上,以及程序是如何执行的,读者能够更好地理解程序的行为为什么是这样的,以及效率低下是如何造成的。
全书将软硬件串在一起帮助我们描述了程序是怎么在系统中工作的,书中的链接加载程序布局等我在《程序员的自我修养》中读到过,其余很多知识和计算机原理、 *** 作系统、系统编程也有很多重叠,总体说来内容并不是很陌生,但仍然有不少收获。第三部分io网络并发三章尚未阅读
写下之下的这些文字是为了帮助自己更好的复习全书的内容,尤其是自己以前掌握不深刻的部分
书的第一部分是全书的精华,主要讲程序与硬件,第四章除外,我没有看
第二章,重点是数的表示方法
移位运算算术右移和逻辑右移的区别
字节顺序大端和小端
数的格式转换先改变大小,再改变有无符号,无符号有符号隐式转换带来的灾难
整数的运算主要是各种溢出问题
浮点数乘法不具备可结合性,转换为整数时可溢出
第三章,重点是汇编程序,个人认为收获最大的一章
各种指令,mov,leal,移位,运算,控制,条件传送指令*,
各种逆向工程,结合习题很有意思
函数调用时帧栈结构
联合、结构数据分布和对齐的问题
内存越界和缓冲区溢出
64位(没有太仔细看,寄存器多了大了,函数调用有很多不同,很多函数不需要栈帧,参数通过寄存器传送)
第五章,程序优化,全章由一个例子贯穿始末,量化了不同方法带来的性能改进
编译器优化的局限性,限制这种能力的原因有:存储器别名的情况,函数调用(静态变量,可重入)
循环优化,不变的变量只算一次
减少函数调用(性能和可读性的折衷)
不必要的内存引用(尽量用临时变量在寄存器中,避免不必要的内存读写)
从处理器的角度考虑(流水、预测分支、关键路径),循环展开,考虑流水(充分利用处理器的多个加法器等,超标量)
程序剖析的工具 gprof
第六章,存储器层次结构
各种存储技术,寄存器,SRAM(高速缓存),DRAM(内存),硬盘(传统硬盘、固态硬盘),网络
各种缓存,高速缓存L1L2是内存的缓存,内存是硬盘的缓存,各种缓存的管理机制(这里只讲了高速缓存的,后面会将内存管理)
程序的局部性,时间和空间的
第二部分,主要将程序在系统的中的运行,这一部分和前一部分差距较大,原因是这一部分凯乎我比较熟?
第七章,链接
可以参见《程序员的自我修养》这本书,主要是目标文件格式阿,符号解析阿,重定位阿的,内容比较简略
静态库的链接顺序,经常会出错的一个问题
一些工具的使用,readelf,objdump,ldd
感觉从这一章物孙或开始,翻译就很不给力了
第八章,名字很奇特,叫异常控制流,讲了各个层面的异常,其实我觉得这一章还不如叫进程
四类异常:中断(IO设备),陷阱(trap,咋这么翻译呢,系统陷入多好听,主要是系统调用),故障(缺页),终止
进程相关,fork,execve,wait,waitpid
信号,读后感《《深入理解计算机系统》-读后感》。signal
非本地跳转,软异常?setjmp,longjmp,据说是try\\catch实现的基础
一些工具(pmap,strace,ps,top)
第九章,虚拟存储器,重点应该是内存管理,地址翻译的机制,我讨厌有些地方该叫内存却叫做存储器
内存管理,主要做了两件事,从虚拟地址到物理地址的翻译,提供了内存读写的保护(只读的内存不能写,只读写的不能运行)
动态内存的分配,给出了几种分配器的数据结构,这一部分没有仔细看
垃圾回收
各种内存的错误,总结的很好,基本我都犯过
回头再看第一章,人家总结的真好,整个一个计算机系统就是一个大抽象,把各种硬件系统抽象为一些简单的概念,这些概念让我们这些程序员能够轻松的处理程序而不用再管硬件了,伟大啊
三个基本抽象:
文件--负责抽象IO设备
虚拟存储器--负责抽象IO设备、内存
进程--负责抽象IO设备、内存、处理器
整本书就是负责介绍怎么抽象的
〔《深入理解计算机系统》-读后感〕随文赠言:【这世上的一切都借希望而完成,农夫不会剥下一粒玉米,如果他不曾希望它长成种粒;单身汉不会娶妻,如果他不曾希望有孩子;商人也不会去工作,如果他不曾希望因此而有收益。】
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)