Linux系统通过转换为静态可执行文件提高性能 (linux so 转静态)

随着计算机技术的不断发展和进步,计算机的性能要求也越来越高。在Linux操作系统的应用中,提高性能的方法有很多种,而本文将介绍一种通过将Linux系统转换为静态可执行文件的方式来提高性能的方法。

软件开发的过程中,往往需要调用一些库函数来实现一些功能。这些库函数通常都是动态链接库,也就是so文件。在一次程序运行中,同一个so文件只会被加载一次,并且会被加载多次的代码段也只会被加载一份,这就保证了内存中有多个进程时,系统可以共享库实例,从而节省内存空间。但是,动态链接库也有其不足之处,就是每次调用这些库函数时,系统都需要到磁盘上查找这些动态链接库文件,并加载这些文件,这就导致了一定的性能损失。

而与动态链接库相对应的概念则是静态链接库,也就是a文件。当使用了静态链接库时,系统在链接时会将所需要的库文件中用到的函数或变量全部复制到可执行文件中,这就使得在运行时不需要到磁盘上去寻找动态链接库文件,从而可以提高程序的运行效率。

Linux系统也可以类比于应用程序,将其从动态链接库方式转换为静态链接库。换句话说,就是将Linux系统转换为一个静态可执行文件。对于这个过程,有很多种实现方式,其中更流行的方式就是使用initramfs技术。

initramfs技术是一种内存文件系统,它包含了启动Linux系统所必需的一些文件,将这些文件全部导入到内存中,然后使用这些文件来引导系统。如果我们将Linux系统全部导入到内存中,那么就相当于将其转换为一个静态可执行文件。这样每次系统运行时就不需要到磁盘上去读取文件了,从而可以提高系统的性能。

将Linux系统转换为静态可执行文件,需要先将系统中所有的动态链接库全部编译为静态链接库,然后再使用initramfs技术将系统转换为静态可执行文件。这个过程需要一定的技术和认识,需要对Linux系统的编译、链接和启动过程有一定的了解。

当Linux系统被转换为静态可执行文件之后,可以发现系统的启动速度明显提高了。这是因为在静态链接库的情况下系统中的所有代码都位于可执行文件中,不需要到磁盘上去寻找动态链接库文件,从而可以加快系统的启动速度。此外,由于静态链接库的引入,还能提高程序在运行时的执行效率,从而提高整个系统的性能。

虽然将Linux系统转换为静态可执行文件可以提高系统的性能,但是它也存在一些缺点。首先是系统容易出现更新问题,因为更新系统不仅需要考虑内核新版本的更换,还需要更新静态可执行文件本身。由于静态可执行文件会将整个系统全部载入内存,导致系统的资源占用更多,如果系统中的应用程序占用空间比较大,就会出现内存不足的问题。

将Linux系统转换为静态可执行文件可以提高系统的性能,但是也需要我们在使用的时候,根据实际情况进行取舍。如果系统运行速度比较慢,并且没有大量的应用程序需要运行,那么将系统转换为静态可执行文件是一种不错的选择。反之,则需要根据实际情况来选择其他的优化方法。

相关问题拓展阅读:

请问我有一个.so文件,如何在Linux下编程使用呢?

Linux下的.so是基于linux下的动态链接,其功能和作用类似与windows下.dll文件。

下面是关于.so的介绍:

一、引言

通常情况下,对函数库的链接是放在编译时期(compile time)完成的。所有相关的对象文件(object file)与牵涉到的函数库(library)被链接合成一个可执行文件(executable file)。程序在运行时,与函数库再无瓜葛,因为所有需要的函数已拷贝到自己门下。所以这些函数库被成为静态库(static libaray),通常文件名为“lib.a”的形式。

其实,我们也可以把对一些库函数的链接载入推迟到程序运行的时期(runtime)。这就是如雷贯耳的动态链接库(dynamic link library)技术。

二、动态链接库的特点与优势

首先让我们来看一下,把库函数推迟到程序运行时期载入的好处:

1. 可以实现进程之间的资源共享。

什么概念呢?就是说,某个程序的在运行中要调用某个动态链接库函数的时候,操作系统首先会查看所有正在运行的程序,看在内存里是否已有此库函数的拷贝了。如果有,则让其共享那一个拷贝;只有没有才链接载入。这样的模式虽然会带来一些“动态链接”额外的开销,却大大的节省了系统的内存资源。C的标准库就是动态链接库,也就是说系统中所有运行的程序共享着同一个C标准库的代码段。

2. 将一些程序升级变得简单。用户只需要升级动态链接库,而无需重新编译链接其他原有的代码就可以完成整个程序的升级。Windows 就是一个很好的例子。

3. 甚至可以真正坐到链接载入完全由程序员在程序代码中控制。

程序员在编写程序的时候,可以明确的指明什么时候或者什么情况下,链接载入哪个动态链接库函数。你可以有一个相当大的软件,但每次运行的时候,由于不同的操作需求,只有一小部分程序被载入内存。所有的函数本着“有需求才调入”的原则,于是大大节省了系统资源。比如现在的软件通常都能打开若干种不同类型的文件,这些读写操作通常都用动态链接库来实现。在一次运行当中,一般只有一种类型的文件将会被打开。所以直到程序知道文件的类型以后再载入相应的读写函数,而不是一开始就将所有的读写函数都载入,然后才发觉在整个程序中根本没有用到它们。

三、动态链接库的创建

由于动态链接库函数的共享特性,它们不会被拷贝到可执行文件中。在编译的时候,编译器只会做一些函数名之类的检查。在程序运行的时候,被调用的动态链接库函数被安置在内存的某个地方,所有调用它的程序将指向这个代码段。因此,这些代码必须实用相对地址,而不是绝对地址。在编译的时候,我们需要告诉编译器,这些对象文件是用来做动态链接库的,所以要用地址不无关代码(Position Independent Code (PIC))。

对gcc编译器,只需添加上 -fPIC 标签,如:

gcc -fPIC -c file1.c

gcc -fPIC -c file2.c

gcc -shared lib.so file1.o file2.o

注意到最后一行,-shared 标签告诉编译器这是要建立动态链接库。这与静态链接库的建立很不一样,后者用的是 ar 命令。也注意到,动态链接库的名字形式为 “lib.so” 后缀名为 “.so”

四、动态链接库的使用

使用动态链接库,首先需要在编译期间让编译器检查一些语法与定义。

这与静态库的实用基本一样,用的是 -Lpath 和 -l 标签。如:

gcc file1.o file2.o -Lpath -l -o program.exe

编译器会先在path文件夹下搜索lib.so文件,如果没有找到,继续搜索lib.a(静态库)。

在程序运行期间,也需要告诉系统去哪里找你的动态链接库文件。在UNIX下是通过定义名为 LD_LIBRARY_PATH 的环境变量来实现的。只需将path赋值给此变量即可。csh 命令为:

setenv LD_LIBRARY_PATH   your/full/path/to/dll

一切安排妥当后,你可以用 ldd 命令检查是否连接正常。

ldd program.exe

动态链接库*.so的编译与使用- –

动态库*.so在linux下用c和c++编程时经常会碰到,最近在网站找了几篇文章介绍动态库的编译和链接,总算搞懂了这个之前一直不太了解得东东,这里做个笔记,也为其它正为动态库链接库而苦恼的兄弟们提供一点帮助。

1、动态库的编译

下面通过一个例子来介绍如何生成一个动态库。这里有一个头文件:so_test.h,三个.c文件:test_a.c、test_b.c、test_c.c,我们将这几个文件编译成一个动态库:libtest.so。

so_test.h:

#include   “stdio.h”

void test_a();

void test_b();

void test_c();

test_a.c:

#include “so_test.h”

void test_a()

{

printf(“this is in test_a…/n”);

}

test_b.c:

#include “so_test.h”

void test_b()

{

printf(“this is in test_b…/n”);

}

test_a.c:

#include “so_test.h”

void test_c()

{

printf(“this is in test_c…/n”);

}

将这几个文件编译成一个动态库:libtest.so

$ gcc test_a.c test_b.c test_c.c -fPIC -shared -o libtest.so

2、动态库的链接

在1、中,我们已经成功生成了一个自己的动态链接库libtest.so,下面我们通过一个程序来调用这个库里的函数。程序的源文件为:test.c。

test.c:

#include “so_test.h”

int main()

{

test_a();

test_b();

test_c();

return 0;

}

l 将test.c与动态库libtest.so链接生成执行文件test:

$ gcc test.c -L. -ltest -o test

l 测试是否动态连接,如果列出libtest.so,那么应该是连接正常了

$ ldd test

l 执行test,可以看到它是如何调用动态库中的函数的。

3、编译参数解析

最主要的是GCC命令行的一个选项:

-shared 该选项指定生成动态连接库(让连接器生成T类型的导出符号表,有时候也生成弱连接W类型的导出符号),不用该标志外部程序无法连接。相当于一个可执行文件

l -fPIC:表示编译为位置独立的代码,不用此选项的话编译后的代码是位置相关的所以动态载入时是通过代码拷贝的方式来满足不同进程的需要,而不能达到真正代码段共享的目的。

l -L.:表示要连接的库在当前目录中

l -ltest:编译器查找动态连接库时有隐含的命名规则,即在给出的名字前面加上lib,后面加上.so来确定库的名称

l LD_LIBRARY_PATH:这个环境变量指示动态连接器可以装载动态库的路径。

l 当然如果有root权限的话,可以修改/etc/ld.so.conf文件,然后调用 /in/ldconfig来达到同样的目的,不过如果没有root权限,那么只能采用输出LD_LIBRARY_PATH的方法了。

4、注意

调用动态库的时候有几个问题会经常碰到,有时,明明已经将库的头文件所在目录 通过 “-I” include进来了,库所在文件通过 “-L”参数引导,并指定了“-l”的库名,但通过ldd命令察看时,就是死活找不到你指定链接的so文件,这时你要作的就是通过修改 LD_LIBRARY_PATH或者/etc/ld.so.conf文件来指定动态库的目录。通常这样做就可以解决库无法链接的问题了。

-lxx

xx是你的.so文件名

其实使用方法和你使用数学库函数是一样的,

源代码

中添加

#include ,编译的时候,加上-lm参数。

注:linux下的.so文件为共享库,相当于windows下的dll文件。

扩展资料: 

linux下编写调用so文件实例

.so是Linux(Unix)下的

动态链接库

. 和.dll类似. 

比如:

文件有: a.c, b.c, c.c 

gcc -c a.c 

gcc -c b.c 

gcc -c c.c 

gcc -shared libXXX.so a.o b.o c.o 

要使用的话也很简单. 比如编译d.c, 使用到libXXX.so中的函数, libXXX.so地址是MYPATH 

gcc d.c -o d -LMYPATH -lXXX 

注意不是-llibXXX

test.c文件和一个test.h,这两个文件要生成libsotest.so文件。然后我还有一个testso.c文件,在这个文件里面调用libsotest.so中的函数。

编写的过程中,首先是编译so文件,我没有编写makefile文件,而是参考的2里面说的直接写的gcc命令。

因为so文件里面没有

main函数

,所以是不可执行的,所以编译的时候要加上-c,只生成目标文件。

linux下的.so文件为共享库,相当于windows下的dll文件,使用方法如下:

在你的工程源代码里包含.h头文件,然后可以调用动态库里的函数,在链接的时候加上如下编译器参数:

-l xx.so

如果你的so文件是以lib开头的,还可以直接这样使用:

-lxx

xx是你的.so文件名

其实使用方法和你使用数学库函数是一样的,源代码中添加

#include ,编译的时候,加上-lm参数。

动态链接库,调用,写c语言时用的。放在编译的文件夹里面。包含进去.h就行了、、、、、、、、

安装个开发工具 然后编译就行了 redhat在安装的时候选择自定义就可以安装开发工具 make 然后make install

linux动态库和静态库的区别

动态库时 程序运行时 加载的 并不包含在程序本身内.

而静态库则是编译进程序里的, 运行时不需要外部的库, 但这样会使程序本身变的臃肿..

动态知纳库一般是 xx.so.x.xx 前面名称, 后面版本, 动态库搭旦没也成为共享库.

静态库迟举则是 x.a 以 .a结尾

静态库:这类库旁备穗的名字一般是lib.a,为库的名字。利用静态函数库编译成的文件比较大,因为整个函数库的所有数据都会被整合进目标代码中,他的优点就显而易见了,即编译后的执行程序不需要外部的函数库支持,因为所有使用的函数都已经被编译进去了。当然这也会成为他的缺点,因为如果静态函数库改变了,那么你的程序必须重新编译。

动态库:这类库的名字一般是lib.M.N.so,同样的为库的名字,M是库的主版本号,N是库的副版本号。当然也可以不要版本号,但名字必须有。相对于静态函数库,动态函数库在编译的时候并没有被编译进目标代码中,你的程序执行到相关函数时才调用该函数库里的相应函数,因此动态函数库所产生的可执行文件比较小。由于函数库没有被整合进你的程序,而是程序运行时动态的申请并调用,所以程序的运行环境中滚轿必须提供相应的库。动态函数库的改变并不影响你的程序,所以动态函数库的升级比较方便。linux系统有几个重要的目录存放相应的函数库,如/lib /usr/lib。

当要使用静态的程序库时,连接器会找出程序所需的函数,然后将它们拷贝到执行文件,由于这种拷贝是完整的,所以一旦连接成功,静态程序库也就不再需要了。然而,对动态库而言,就不是这样。动态库会在执行程序内留下一个标记指明当程序执行时,首先必须载入这个库。由于动态库节省空间,linux下进行连接的缺省操作是首先连接动态库,也就是运卜说,如果同时存在静态和动态库,不特别指定的话,将与动态库相连接。

静态库是什么?可冲定位目标文件以一种特定的方式打包成一个单独的文件,并腊敬且在链接生成可执行文件时,从这个单独的文件中拷贝自己需要的内容到最终的可执行文件中,这个单独的文件,被称为静态库,Linux中通常以.a(archive)为后缀。

动态库是什么?动态库可静态库类似,但是它并不在链接时将需要的二进制代码都拷贝到可执行文件中,而是仅仅拷贝一些重定位和符号表信息,这些信息可以在程序运行时完成真正的链接过程,Linux中通常以.so(shared

object)作为后缀。

有什么区别呢?

1、可执行文件大小不一样:静态链接的可执行文件比动态链接的可执行文件要大得多,因为它将需要用到的代码从二进制文件中拷贝了一份,而动态库仅仅是复制了一些重定位世哪和符号表信息。

2、占用磁盘大小不一样:如果有多个可执行文件,那静态库中的同一个函数的代码就会被复制多份,而动态库只有一份,因此使用静态库占用的磁盘空间相比动态库要大。

3、扩展性与兼容性不一搜局码样:如果静态库中某个函数的实现变了,那么可执行文件必须重新编译,而对于动态链接生成的可执行文件,只需要更新动态库本身即可,不需要重新编译可执行文件。

Linux中没有动态库,只有称作共享库的类似概念的库。

共享胡稿伏库是被编译成二进制机器码的可执行文件。

静态库是编译成目标代码敬激的不可执行文件,使用静态库需要裤携客户程序通过源代码编译再与静态库一起连接的过程才能变成可执行文件

关于linux so 转静态的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。


数据运维技术 » Linux系统通过转换为静态可执行文件提高性能 (linux so 转静态)