(转)linux程序减肥三步走

对于设计嵌入式Linux系统的研发人员来说,有一个问题是必须要考虑到的,那就是存储器的空间。 
我们知道嵌入式Linux系统所用的存储器不是软磁盘、硬盘、ZIP盘、CD-ROM、DVD这些众所周知的大容量常规存储器,它使用的是例如Rom, CompactFlash,M-Systems的DiskOnChip,SONY的MemoryStick,IBM的MicroDrive等体积极小,与主板上的BIOS大小相近,存储容量很小的存储器。所以怎样尽可能的节省空间就显的很重要。 
    嵌入式系统的存储器中放置的无非是内核,文件系统,软件,以及自己开发的程序。本文就从程序入手,以一个非常简单的C程序来作为例子,通过三步来让它减肥。 
Hello.c: 
#include 
int main () 

   printf ("hello,world"); 
   return 0; 

我们先用正常的编译方法来编译,看看生成的程序的大小是多少 
#gcc –o hello hello.c 
#ls –l hello 
-rwxr-xr-x 1 root root 11542 Nov 13 20:07 hello 
从结果可以看到正常编译后的程序大小是11542Byte, 现在开始我们的三步减肥,看看到底效果如何。 
步骤一:用gcc 的代码优化参数 
    代码优化指的是编译器通过分析源代码,找出其中尚未达到最优的部分,然后对其重新进行组合,目的是改善程序的执行性能。GCC提供的代码优化功能非常强大, 它通过编译选项-On来控制优化代码的生成,其中n是一个代表优化级别的整数。对于不同版本的GCC来讲,n的取值范围及其对应的优化效果可能并不完全相同,比较典型的范围是从0变化到2或3。 
    编译时使用选项-O可以告诉GCC同时减小代码的长度和执行时间,其效果等价于-O1。在这一级别上能够进行的优化类型虽然取决于目标处理器,但一般都会包括线程跳转(Thread Jump)和延迟退栈(Deferred Stack Pops)两种优化。选项-O2告诉GCC除了完成所有-O1级别的优化之外,同时还要进行一些额外的调整工作,如处理器指令调度等。选项-O3则除了完 成所有-O2级别的优化之外,还包括循环展开和其它一些与处理器特性相关的优化工作。通常来说,数字越大优化的等级越高,同时也就意味着程序的运行速度越 快。许多Linux程序员都喜欢使用-O2选项,因为它在优化长度、编译时间和代码大小之间,取得了一个比较理想的平衡点。 
#gcc –O2 –o hello hello.c 
#ls –l hello 
-rwxr-xr-x 1 root root 11534 Nov 13 20:09 hello 
    优化过的程序的大小是11534Byte,比正常编译的结果11542Byte似乎没有小多少,不过不用着急,这才是第一步。我们接着往下进行。 
步骤二:用strip 命令 
    
我们知道二进制的程序中包含了大量的符号信息(symbol table),有一部分是用来为gdb除错提供必要帮助的。可以通过readelf –S查看到这些符号信息。 
#readelf -S hello 
Section Headers: 
[Nr] Name Type 
[ 0] NULL 
[ 1] .interp PROGBITS 
[ 2] .note.ABI-tag NOTE 
[ 3] .hash HASH 
[ 4] .dynsym DYNSYM 
[ 5] .dynstr STRTAB 
[ 6] .gnu.version VERSYM 
[ 7] .gnu.version_r VERNEED 
[ 8] .rel.dyn REL 
[ 9] .rel.plt REL 
[10] .init PROGBITS 
[11] .plt PROGBITS 
[12] .text PROGBITS 
[13] .fini PROGBITS 
[14] .rodata PROGBITS 
[15] .eh_frame PROGBITS 
[16] .data PROGBITS 
[17] .dynamic DYNAMIC 
[18] .ctors PROGBITS 
[19] .dtors PROGBITS 
[20] .jcr PROGBITS 
[21] .got PROGBITS 
[22] .bss NOBITS 
[23] .comment PROGBITS 
[24] .debug_aranges PROGBITS 
[25] .debug_pubnames PROGBITS 
[26] .debug_info PROGBITS 
[27] .debug_abbrev PROGBITS 
[28] .debug_line PROGBITS 
[29] .debug_frame PROGBITS 
[30] .debug_str PROGBITS 
[31] .shstrtab STRTAB 
[32] .symtab SYMTAB 
[33] .strtab STRTAB 
    类似于.debug_xxxx的就是用来gdb除错的。去掉它们不但不会影响程序的执行还可以减小程序的size。这里我们通过strip命令拿掉它们。 
#strip hello 
#ls –l hello 
-rwxr-xr-x 1 root root 2776 Nov 13 20:11 hello 
程序立刻变成2776Byte了,效果不错吧。让我们再接再厉,进行最后一步。 
步骤三:用objcopy 命令 
    
上一步的strip命令只能拿掉一般symbol table,有些信息还是没拿掉,而这些信息对于程序的最终执行是没有什幺影响的。如:.comment; .note.ABI-tag; .gnu.version就是完全可以去掉的。所以说程序还有简化的余地,我们可以使用objcopy命令把它们抽取掉。 
#objcopy –R .comment –R .note.ABI-tag –R .gnu.version hello hello1 
#ls –l hello1 
-rwxr-xr-x 1 root root 2316 Nov 13 20:23 hello1 
    到这一步,程序的减肥就完成了,我们可以看到程序由正常编译的11542Byte 一下子渐少到2316Byte,效果非常明显。 
小结 
    
程序容量的减小无疑对嵌入式Linux系统的设计有着重要的意义,它为我们节省了大量空间,使得我们可以利用这部分空间来完善我们的系统,比如加大内核等等,毕竟这才是我们最终的目的。

(转)linux程序减肥三步走

时间: 2024-10-20 22:16:54

(转)linux程序减肥三步走的相关文章

80后女孩买房三步走 短期增值是首步 资金 增值 理财_新浪财经_新浪网

三湘华声全媒体记者 梁兴 通讯员 王茜 [个案资料] 尹婵,今年28岁,是长沙一名普通的公司职员.步入社会5年以来,月收入一直在4500元左右,但因勤俭节约,月结余能达到3000元,年终奖5000元.目前有存款18万元,有"五险一金",无任何商业保险. 尹婵是土生土长的长沙姑娘,父母工资收入稳定.由于工作后仍和父母一起居住,不需要承担房租或房贷.虽然父母乐意提供食宿,但是尹婵不想做"啃老族",每月给父母800元"搭伙费". [财务诊断] 尹婵工作

ping排错三步走

ping排错三步走--------- 每次访问目标主机的过程是这样的: 客户端->网关->DNS->客户端(拿着解析出来的IP)->目标服务器 所以当ping不通的时候,就从这三个地方找问题,有以下三种可能: (1)网关不通 (2)DNS域名解析服务器不通 (3)主机服务器不通 一:ping 网关,如果网关不通: 可能原因:(1)网卡没起来 (2)网线断了 排查方式: (1)查看本地ip地址`ifconfig` ,是不是没连上网. (2)查看路由表`route -n` 是否有相同网

Ceph对象存储RGW对接企业级网盘OwnCloud三步走

上篇文章我们把Ceph对象存储搭建成功了,但是成功了之后我们怎么用呢?下面我们本文就来讲下Ceph对象存储对接企业私有云网盘OwnCloud. OwnCloud分为企业版和社区版,我们只说社区版,在这里我就不多赘述了. 那么Ceph对接OwnCloud分三步走. 第一:安装Ceph配置RGW对象存储 第二:安装OwnCloud 第三:对接 第一步在上个文章里面已经做了,那么第二步是安装OwnCloud,可以看下我之前的文章进行安装. 如何搭建OwnCloud网盘 主要讲下第三步 要点:网盘节点D

Python学习笔记(一)三步走安装pip

pip是用来方便地管理Python的第三方包的,由于此前玩Python仅仅是浅尝辄止,用的是python(x,y),但是这里并不代表你想用什么包都能从里面找到的,所以我把python(x,y)卸了,然后重新装了个Python2.7.5,准备尝试一下用pip来下载想要的包. 不过pip也有一个麻烦之处,如果电脑不能联网怎么办? 之后再考虑这个问题,先在此记录一下我是如何安装pip的.本文参考百度经验<如何在win7下安装python包工具pip>,网上有很多pip安装教程,但感觉这个写的是最简明

小学生手抄报制作三步走

小学生手抄报制作三步走      小学生手抄报,不管是英语手抄报.科技手抄报还是环保手抄报,不管是安全.数学.读书.迎奥运还是等方面的内容,大抵都有同样的要求.那么,如何制作一份精彩的手抄报呢?三个步骤:一.确定一个好的手抄报主题           手抄报只有小小一张纸,能够容纳的文章并不多.如果把一个话题方方面面的内容都堆上去,那给读者的感觉可不好.如果手抄报大赛的主题是“七月的滋味”,如果你把七月里怎么玩.怎么学.怎么旅游……统统写上去,就像把苦辣酸甜各种味道的菜搅在一起,味道可好不到哪儿

编写高质量代码——重载operator=的标准三步走

CString& CString::operator=(const CString& str){   if(this == &str)       //1.自赋值检查       return *this;          if(pChar!=NULL)       //2.释放原有空间     delete[]  pCahr;   pChar = new char[strlen(str.pChar)+1]; // 2.申请新空间   strcpy(pChar, str.pCha

Oracle创建&#39;数据库&#39;三步走

--创建表空间 create tablespace waterboss datafile 'd:\waterboss.dbf' size 100m autoextend on next 10m; --创建用户 create user wateruser identified by 011220 default tablespace waterboss; --用户赋权 grant dba to wateruser; Oracle创建'数据库'三步走 原文地址:https://www.cnblogs

git 三步走

git三步走: git add .        (注:别忘记后面的.,此操作是把Test文件夹下面的文件都添加进来) git commit  -m  "提交信息"  (注:"提交信息"里面换成你需要,如"first commit") git push -u origin master   (注:此操作目的是把本地仓库push到github上面,此步骤需要你输入帐号和密码) 有问题的话,看错误信息,对症解决. 原文地址:https://www.c

搞定面试算法系列 —— 分治算法三步走

主要思想 分治算法,即分而治之:把一个复杂问题分成两个或更多的相同或相似子问题,直到最后子问题可以简单地直接求解,最后将子问题的解合并为原问题的解. 归并排序就是一个典型的分治算法. 三步走 和把大象塞进冰箱一样,分治算法只要遵循三个步骤即可:分解 -> 解决 -> 合并. 分解:分解原问题为结构相同的子问题(即寻找子问题) 解决:当分解到容易求解的边界后,进行递归求解 合并:将子问题的解合并成原问题的解 这么一说似乎还是有点抽象?那我们通过经典的排序算法归并排序来体验一下分治算法的核心思想.