作者: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. C#按字节长度截取字符串

    产生这个问题的原因是将Substring方法将双字节的汉字当成一个字节的字符(UCS2字符)处理了,导致长度变短. 两个扩展方法按字节长度截取字符串 /// <summary> /// 根 ...

  2. 基于 Apache Mahout 构建社会化推荐引擎

    基于 Apache Mahout 构建社会化推荐引擎 http://www.ibm.com/developerworks/cn/views/java/libraryview.jsp 推荐引擎利用特殊的 ...

  3. HTML中的div标签

    在网页制作过程过中,能够把一些独立的逻辑部分划分出来.放在一个<div>标签中,这个<div>标签的作用就相当于一个容器. 为了使逻辑更加清晰,我们能够为这一个独立的逻辑部分设 ...

  4. 完美攻略心得之圣魔大战3(Castle Fantisia)艾伦希亚战记(艾伦西亚战记)包含重做版(即新艾伦希亚战记)

    (城堡幻想曲3,纠正大家个错误哦,不是圣魔大战3,圣魔大战是城堡幻想曲2,圣魔大战不是个系列,艾伦西亚战记==艾伦希亚战记,一个游戏日文名:タイトル キャッスルファンタジア -エレンシア戦記-リニュー ...

  5. C++习题 虚函数-计算图形面积

    C++习题 虚函数-计算图形面积 Time Limit: 1 Sec  Memory Limit: 128 MB Submit: 122  Solved: 86 [cid=1143&pid=6 ...

  6. python学习1(小白记录)

    python创建cocos2d-x项目注意点1. 2.7.5版本号的.配置好环境变量之后.要切换到tools文件夹下.直接运行 python create_project.py ..........这 ...

  7. hdu 4472 Count (2012 ACM-ICPC 成都现场赛)

    递推,考虑到一n可以由i * j + 1组合出来,即第二层有j个含有i个元素的子树...然后就可以了.. #include<algorithm> #include<iostream& ...

  8. Webserver管理系列:1、安装Windows Server 2008

    简单了解下server: 1U: 2U: 3U: 在安装Windows Server 2008之前我们先了解下Windows Server 2008: Windows Server 2008是微软一个 ...

  9. oracle看到用户的所有表名、表睐、字段名称、现场的目光、是空的、字段类型

    --oracle看到用户的所有表名.表睐.字段名称.现场的目光.是空的.字段类型 select distinct TABLE_COLUMN.*, TABLE_NALLABLE.DATA_TYPE, T ...

  10. hadoop namenode -format Couldn&#39;tload main class &quot;-Djava.library.path=.home.hadoop.hadoop-2.5.2.lib&quot;

    <pre name="code" class="sql">[hadoop@MasterHadoop50 ~]$ hadoop namenode -f ...