作者:zhanhailiang 日期:2014-10-26

linux程序动态库载入流程简单介绍

linux从程序(program或对象)变成进程(process或进程),简单说来须要经过三步:

  1. fork进程,在内核创建进程相关内核项,载入进程可运行文件;
  2. 查找依赖的.so,逐一载入映射虚拟地址;
  3. 初始化程序变量;

例如以下例通过strace查看pwd命令运行过程:

[root@~/wade/codeReview/learningc]# strace pwd
execve("/bin/pwd", ["pwd"], [/* 24 vars */]) = 0
brk(0) = 0x1c77000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f06eb011000
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=29690, ...}) = 0
mmap(NULL, 29690, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f06eb009000
close(3) = 0
open("/lib64/libc.so.6", O_RDONLY) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0p\356\1\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=1921096, ...}) = 0
mmap(NULL, 3750152, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f06eaa5f000
mprotect(0x7f06eabe9000, 2097152, PROT_NONE) = 0
mmap(0x7f06eade9000, 20480, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x18a000) = 0x7f06eade9000
mmap(0x7f06eadee000, 18696, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f06eadee000
close(3) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f06eb008000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f06eb007000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f06eb006000
arch_prctl(ARCH_SET_FS, 0x7f06eb007700) = 0
mprotect(0x7f06eade9000, 16384, PROT_READ) = 0
mprotect(0x7f06eb012000, 4096, PROT_READ) = 0
munmap(0x7f06eb009000, 29690) = 0
brk(0) = 0x1c77000
brk(0x1c98000) = 0x1c98000
open("/usr/lib/locale/locale-archive", O_RDONLY) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=99158576, ...}) = 0
mmap(NULL, 99158576, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f06e4bce000
close(3) = 0
getcwd("/root/wade/codeReview/learningc", 4096) = 32
fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 1), ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f06eb010000
write(1, "/root/wade/codeReview/learningc\n", 32/root/wade/codeReview/learningc
) = 32
close(1) = 0
munmap(0x7f06eb010000, 4096) = 0
close(2) = 0
exit_group(0) = ?

由此可见。假设仅仅载入必须的动态库对程序性能有非常重要的意义。

最佳实践

1. 程序test.c:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
main () {
printf ("1");
exit (0);
}

2. 编译test.c

[root@~/wade/codeReview/learningc/16]# gcc -lm -lpthread -o test test.c 

3. 通过ldd test命令查看程序执行时须要载入哪些动态库:

[root@~/wade/codeReview/learningc/16]# ldd test
linux-vdso.so.1 => (0x00007fff6b5ff000)
libm.so.6 => /lib64/libm.so.6 (0x00007f394cefa000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f394ccdd000)
libc.so.6 => /lib64/libc.so.6 (0x00007f394c948000)
/lib64/ld-linux-x86-64.so.2 (0x00007f394d187000)

4. 通过ldd -u test命令查看程序载入了哪些不必要的动态库:

[root@~/wade/codeReview/learningc/16]# ldd -u test
Unused direct dependencies:
 
/lib64/libm.so.6
/lib64/libpthread.so.0

5. 通过-Wl,–as-needed编译选项仅仅载入必须的动态库:

[root@~/wade/codeReview/learningc/16]# gcc -Wl,--as-needed -lm -o test test.c
[root@~/wade/codeReview/learningc/16]# ldd test
linux-vdso.so.1 => (0x00007fffdf5ff000)
libc.so.6 => /lib64/libc.so.6 (0x00007f5d862cd000)
/lib64/ld-linux-x86-64.so.2 (0x00007f5d8666a000)

參考文章:

版权声明:本文博主原创文章,博客,未经同意不得转载。

LinuxDLL加载优化方案的更多相关文章

  1. vue加载优化方案

    我们的项目随着组件的加入,首次加载的js文件越来越大,用户等待时间越来越长:之前想着使用webpack的splitCoding来解决,看了webpack的官方文档可以配置optimization的 m ...

  2. 关于cocos2dx for lua资源加载优化方案

    之前我写游戏加载都是从一个json文件写入要加载的文件名来实现加载,但是如果资源 比较多的情况下,会导致非常难管理,需要逐个写入.所以换了另外一种方式来加载文件. 首先,我是通过场景之前的切换时候,加 ...

  3. vue项目首屏加载优化实战

    问题 单页面应用的一个问题就是首页加载东西过多,加载时间过长.特别在移动端,单页面应用的首屏加载优化更是绕不开的话题.下面我会写出我在项目中做的一些优化,希望大家能够相互讨论,共同进步. 我的项目vu ...

  4. Vue SPA 首屏加载优化实践

    写在前面 本文记录笔者在Vue SPA项目首屏加载优化过程中遇到的一些坑及优化方案! 我们以 vue-cli 工具为例,使用 vue-router 搭建SPA应用,UI框架选用 element-ui ...

  5. js资源加载优化

    互联网应用或者访问量大的应用,对js的加载优化是不可少的.下面记录几种优化方法 CDN  + 浏览器缓存 CDN(content delivery network)内容分发网络, 最传统的优化方式.其 ...

  6. Quick-Cocos2d-x v3.3 异步加载Spine方案 转

    Quick-Cocos2d-x v3.3 异步加载Spine方案 浩月难求也与2015-03-25 15:06:3441 次阅读 背景 项目中使用了Quick-Cocos2d-x 3.3,由于Spin ...

  7. 请给出异步加载js方案

    请给出异步加载js方案,不少于两种 默认情况javascript是同步加载的,也就是javascript的加载时阻塞的,后面的元素要等待javascript加载完毕后才能进行再加载,对于一些意义不是很 ...

  8. Android热修复(动态加载)方案汇总

    整理了以下动态加载的方案,便于在项目中使用时查阅: Dexposed github (https://github.com/alibaba/dexposed) AndFix github (https ...

  9. vue加载优化策略

    vue.js是一个比较流行的前端框架,与react.js.angular.js相比来说,vue.js入手曲线更加流畅,不管掌握多少都可以快速上手.但是单页面应用也都有其弊病,有时候首屏加载慢的让人捏舌 ...

随机推荐

  1. OCP-1Z0-051-题目解析-第29题

    29. Which two statements are true regarding constraints? (Choose two.)  A. A foreign key cannot cont ...

  2. 获取不同机型外置SD卡路径

    /** * 运行挂载命令.返回挂载的地址.然后将地址解析 */ private void getExtSDCardPath() { try { Runtime runtime = Runtime.ge ...

  3. c++进阶

    对网络编程/多线程/系统编程有一定了解:4:对ngnix,redis,memcache有一定了解:5:有高并发服务开发经验优先: 因为C/C++在嵌入式.移动互联网.物联网有很大的优势,有很多人就靠一 ...

  4. ok6410 u-boot-2012.04.01移植七完善u-boot移植(u-boot移植结束)

    继ok6410 u-boot-2012.04.01移植六后,开发板已支持MLC NAND.DM9000等.但还需要完善比如环境变量.mtdpart分区.裁剪.制作补丁等.下面的工作就是完善移植的u-b ...

  5. Nginx将请求分发到各web应用

    介绍了VMWare12虚拟机.Linux(CentOS7)系统安装.部署Nginx1.6.3代理服务做负载均衡.接下来介绍通过Nginx将请求分发到各web应用处理服务. 一.Web应用开发 1.as ...

  6. WPF动态改变主题颜色

    原文:WPF动态改变主题颜色 国内的WPF技术先行者周银辉曾介绍过如何动态改变应用程序的主题样式,今天我们来介绍一种轻量级的改变界面风格的方式--动态改变主题色. 程序允许用户根据自己的喜好来对界面进 ...

  7. Troubleshooting &quot;Global Enqueue Services Deadlock detected&quot; (Doc ID 1443482.1)

    In this Document   _afrLoop=1021148011984950&id=1443482.1&displayIndex=1&_afrWindowMode= ...

  8. windows phone 页面导航(6)

    原文:windows phone 页面导航(6) 页面导航的例子我们使用的是两个页面,从第一个页面(MainPage)导航到第二个页面(SecondPage),然后可以从第二个页面导航到第一个页面 , ...

  9. Android应用开发-小巫CSDN博客client之显示博文具体内容

    Android应用开发-小巫CSDN博客客户端之显示博文具体内容 上篇博文给大家介绍的是怎样嵌入有米广告而且获取收益,本篇博客打算讲讲关于怎样在一个ListView里显示博文的具体信息.这个可能是童鞋 ...

  10. 解决.net的堆碎片化带来的内存占用过大的问题

    场景 使用WCF开发的服务端在多个客户端登录后,其服务器的内存占用不断增加. 分析 使用Windbg分析得到内存碎片化严重,其中包含了非常大的空闲空间,最大的一块竟然有150M,真正使用的空间其实很小 ...