使用动态库可以有效减少程序运行时占用的内存,主要方法有:
1. 把公共功能代码编译成动态链接库。将公共模块、框架等代码编译成 .so
共享库文件,程序只动态加载使用,不会重复占用代码内存。
2. 使用外部库的动态链接版本。尽量使用动态链接的外部依赖库(如Qt),而不是静态链接大型库文件。
3. 启用按需加载(on-demand paging)。编译时加入`-Wl,--no-as-needed`参数,程序运行只加载需要的动态库代码页面。
4. 减少动态库重复。不同动态库中重复的公共代码会占用额外内存,优化代码复用可以减少重复。5. 谨慎使用全局变量。全局变量常驻内存,尽量改用局部变量。
6. 优化数据结构。优化链表、散列表等数据结构的内存占用。
7. 避免内存泄漏。处理好动态内存的申请释放,避免隐藏的内存泄漏问题。
8. 正确设置内存页大小。根据代码特点,适当调整内存页的大小。
主要原理:
把公共功能代码编译成动态链接库可以减少程序运行时占用的内存,其主要原理是:
动态链接库中的代码是共享的,它只需要在内存中加载一次,多个程序可以同时访问使用。而静态链接的代码则需要每个程序各自占用一份内存。
具体来说,编译成动态链接库后:
1. 代码只需在磁盘上存一份。不同的程序可以共用这份代码,不需要每个程序都包含一份代码拷贝。
2. 加载动态库时,代码只需要加载一次到内存中,并不会因为加载库的进程数量而线性增长。 Operating System 使用相同的内存页映射此代码段供各进程访问。
3. 由于代码是共享的,也就减少了内存中的重复代码段,降低了内存占用。
4. 只有当程序执行到相关代码时,对应的库代码段页才会加载到内存中,可以按需加载,减少不必要的内存占用。
5. 卸载库时,对应的代码页会由操作系统回收,内存可以释放。综上,动态库实现代码共享,减少冗余占用,是降低程序内存占用的常用手段。 (已编辑)
一个10M的静态库在三个类中都引用,会增加多大的内存
如果一个大小为10MB的静态库(.a文件),被3个不同的可执行程序同时静态链接使用,则大概会增加3 * 10MB = 30MB 的内存占用。
理由如下:1. 静态库中的代码在链接时会被整个拷贝到目标可执行文件中,而不是共享。
2. 三个不同的可执行程序,链接器会分别为它们复制一份完整的静态库代码。
3. 假设静态库文件本身大小为10MB,那么三个程序就会增加3 * 10MB的大小。
4. 程序运行时,这些重复的静态库代码也会被加载到内存中,因此预计会增加30MB的内存占用。
5. 即使静态库代码中有大量公共功能,但由于是静态链接,所以每个程序都要占用完全一样的代码拷贝。
6. 如果将静态库改为动态库,即使加载3次,也只会有一份代码映射到内存中,就可以显著减少内存占用。所以,在多个程序之间共享代码时,使用动态库而不是静态库是减少内存占用的重要手段。 (已编辑)