深入分析linux下 动态库的显性调用(dlopen)和隐性调用区别 您所在的位置:网站首页 什么是动态编译程序设计 深入分析linux下 动态库的显性调用(dlopen)和隐性调用区别

深入分析linux下 动态库的显性调用(dlopen)和隐性调用区别

2024-07-13 23:40| 来源: 网络整理| 查看: 265

1. 前言

在linux环境下编程,我们如果想要使用第三方的库,基本上有以下几种方式:

1、将第三方库的源码合并到我们的工程项目代码中,一起编译。2、将第三方库编译成静态库(xxx.a),我们在使用时,在Makefile中引用该静态库。3、将第三方库编译成动态库(xxx.so), 我们在使用时,隐性调用该动态库,具体表现为需要 在程序中包含动态库的 头文件,同时需要在/usr/lib路径下,存放动态库文件,以便程序调用。4、将第三方库编译成动态库(xxx.so), 我们在使用时,显性调用该动态库,在程序中,不需要包含动态库的头文件,使用 dlopen、dlsym等接口函数调用该动态库。

这4种方式:

第1和2种,本质上是一样的,使用静态库,编译时,会将静态库的内容合并到工程代码中,唯一区别的是当我们拿不到第三方库的源码时,可以直接使用静态库,相当于使用一个黑盒子,静态库提供接口。第3和4种方式,我们常用的是第3种方式,也就是隐性调用,但是显性调用一种程序插件的概念,随用随加载,不用不加载。 2. 显性调用和隐性调用区别

这里我们先说结论:

隐性调用:需要提前将动态库xxx.so 拷贝到 相关目录下,不管程序是否真正使用动态库,执行前会检查该动态库,如果检测不到动态库,会报错。隐性调用,程序一旦执行,会把动态库读到内存中,而不管是否会运行到动态库部分,相当于一刀切。显性调用,如果程序没有运行到dlopen,动态库文件xxx.so 是不需要拷贝到相关目录下的,程序只有在执行到dlopen时,才会检查该动态库,是一种插件形式,随用随调用。显性调用,程序开始运行后,不会立刻读取动态库到内存中,而是直行道dlopen时,才会将动态库拷贝到内存中。 名称使用方式动态库文件内存其他隐性调用引用动态库头文件需要提前拷贝到/usr/lib/目录,否则程序无法执行程序开始执行,不管是否用到动态库功能,都会将动态库读到内存中不会额外调用插件库显性调用不需要引用动态库头文件,但是需要引用不一定,如果程序不会执行到动态库功能,则不需要拷贝,即便使用,也可以使用绝对路径来使用,不需要拷贝到/usr/lib/目录下只有程序执行到dlopen时,才会将动态库读入内存会额外调用linux插件库,来支持显性调用 3. 测试

测试的思路就是对比,对比源码、静态库、动态库显性调用、动态库隐性调用,这4种方式的内存占比情况。

3.1 场景

我们实现一种简单的场景,编写一个 加、减、乘、除、打印等功能的 计算库,主程序中调用该库,计算库源码如下:

#include #include #include const char *CA_crt = \ { \ "-----BEGIN CERTIFICATE-----\r\n" "MIIDkzCCAnugAwIBAgIJAI436FANVXhYMA0GCSqGSIb3DQEBCwUAMF8xCzAJBgNV\r\n" \ "BAYTAkNOMQ4wDAYDVQQIDAVIZWJlaTERMA8GA1UEBwwITGFuZ2ZhbmcxDDAKBgNV\r\n" \ "BAoMA0VOTjEOMAwGA1UECwwFRU5ORVcxDzANBgNVBAMMBklvVCBDQTAgFw0yMTAz\r\n" \ "MTEwODMyMjRaGA8yMTIxMDIxNTA4MzIyNFowXzELMAkGA1UEBhMCQ04xDjAMBgNV\r\n" \ "BAgMBUhlYmVpMREwDwYDVQQHDAhMYW5nZmFuZzEMMAoGA1UECgwDRU5OMQ4wDAYD\r\n" \ "VQQLDAVFTk5FVzEPMA0GA1UEAwwGSW9UIENBMIIBIjANBgkqhkiG9w0BAQEFAAOC\r\n" \ "AQ8AMIIBCgKCAQEAzeteOYou2GlZys4lEo+ypdXYCmpayqSdpZGIaVojLNNYqoQc\r\n" \ "kbghLhxzJxlB72lMc3zOPrYHyG/pe9Abh198sHSU0FInjr6nTx07rUy5SsIKQNIY\r\n" \ "sih8pxVH+7CDp9X+BNhRWGbobE0KnMO+U5XjR4+b7yGDGfaWzBxIaADYJDnbcWEs\r\n" \ "14EfSnADE0I9A2AyqLgZTpr6sj0A8ybowl/SgJW7wT+yrymNbNlzYDZKN4ow1376\r\n" \ "PsXiwtnN0TO2g3x9bYvIjFRpEzcyoW2/eab81ztS81YE3RslfWh74lpviOoB8z7M\r\n" \ "Va3dQIJrsCvRjDkWueuDrw2MmC1R8tB4HtqZxQIDAQABo1AwTjAdBgNVHQ4EFgQU\r\n" \ "h06iXX7GqtF5T19AZzkXhLSSaz4wHwYDVR0jBBgwFoAUh06iXX7GqtF5T19AZzkX\r\n" \ "hLSSaz4wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAuC/J3nO01YxS\r\n" \ "TZuhXtFio3AGkQNptFlsGjWyzxLyH2oJN7PI6KpI2XhteUzRfUN2rx7F9uwpFig8\r\n" \ "yDphOU7fesbvRsAKkb6HhDgeMKcuPrKOM2FMj6JVcyHERJ5J7MaqcRVAS948F54n\r\n" \ "fCAOIfvkd8Y8EmxptDnbyJ7gTwJ4mAYuXJzLtVaEZqMcAvvFdJgKHHNJhl7SqfO3\r\n" \ "c9JJhepx0djWwR4coMc66Fe3X9lDdmhGt/t6TXxI09qGxecpj8p/VuRQ02gcLyZW\r\n" \ "139Yg2JpWUftmyITvBCW1fNM1Uf1GGu6tsFibE+DcwhGNJ0rbBP/EzSFg1trAkUN\r\n" \ "svRnMOVUuQ==\r\n" \ "-----END CERTIFICATE-----" }; int add(int a,int b) { return (a + b); } int sub(int a, int b) { return (a - b); } int mul(int a, int b) { return (a * b); } int div(int a, int b) { return (a / b); } void print_CA_info(void) { printf("%s", CA_crt); }

注: 上述代码中,包含了一个CA证书,目的是为了增加这个 动态库的体积,方便后面的比较,否则动态库太小的话,看不出区别。

测试代码逻辑:

int main(void) { printf("start wait 60s...\n"); sleep(60); printf("will return in 20...\n"); print_CA_info(); sleep(20); return 0; }

上述代码中,有两部分组成,前一部分是未执行动态库内容,进行等待,后一部分则是执行动态库内的函数,这样做的目的是为了 分析 显性调用的 dlopen 前后内存区别。

3.2 源码使用

直接将动态库的源码合并到测试程序里,进行编译,运行,内存监控如下:

ubuntu@VM-0-17-ubuntu:~$ ps -ef|grep test-src ubuntu 3826 3082 0 11:03 pts/3 00:00:00 ./test-src ubuntu 3856 3194 0 11:03 pts/4 00:00:00 grep test-src ubuntu@VM-0-17-ubuntu:~$ pmap -x 3826 3826: ./test-src Address Kbytes RSS Dirty Mode Mapping 000055662853e000 4 4 0 r-x-- test-src 000055662853e000 0 0 0 r-x-- test-src 000055662873f000 4 4 4 r---- test-src 000055662873f000 0 0 0 r---- test-src 0000556628740000 4 4 4 rw--- test-src 0000556628740000 0 0 0 rw--- test-src 000055662a2c3000 132 4 4 rw--- [ anon ] 000055662a2c3000 0 0 0 rw--- [ anon ] 00007f1b03aed000 1948 1164 0 r-x-- libc-2.27.so 00007f1b03aed000 0 0 0 r-x-- libc-2.27.so 00007f1b03cd4000 2048 0 0 ----- libc-2.27.so 00007f1b03cd4000 0 0 0 ----- libc-2.27.so 00007f1b03ed4000 16 16 16 r---- libc-2.27.so 00007f1b03ed4000 0 0 0 r---- libc-2.27.so 00007f1b03ed8000 8 8 8 rw--- libc-2.27.so 00007f1b03ed8000 0 0 0 rw--- libc-2.27.so 00007f1b03eda000 16 12 12 rw--- [ anon ] 00007f1b03eda000 0 0 0 rw--- [ anon ] 00007f1b03ede000 164 164 0 r-x-- ld-2.27.so 00007f1b03ede000 0 0 0 r-x-- ld-2.27.so 00007f1b040fb000 8 8 8 rw--- [ anon ] 00007f1b040fb000 0 0 0 rw--- [ anon ] 00007f1b04107000 4 4 4 r---- ld-2.27.so 00007f1b04107000 0 0 0 r---- ld-2.27.so 00007f1b04108000 4 4 4 rw--- ld-2.27.so 00007f1b04108000 0 0 0 rw--- ld-2.27.so 00007f1b04109000 4 4 4 rw--- [ anon ] 00007f1b04109000 0 0 0 rw--- [ anon ] 00007ffecec06000 132 12 12 rw--- [ stack ] 00007ffecec06000 0 0 0 rw--- [ stack ] 00007ffeceddd000 12 0 0 r---- [ anon ] 00007ffeceddd000 0 0 0 r---- [ anon ] 00007ffecede0000 8 4 0 r-x-- [ anon ] 00007ffecede0000 0 0 0 r-x-- [ anon ] ffffffffff600000 4 0 0 r-x-- [ anon ] ffffffffff600000 0 0 0 r-x-- [ anon ] ---------------- ------- ------- ------- total kB 4520 1416 80

可以看到 占用内存 约 1416kb

3.3 静态库调用

将共享库编译成静态库libcalculate.a,然后在编译测试程序时,引用该静态库,具体的编译步骤这里就省略,运行,监控内存如下:

ubuntu@VM-0-17-ubuntu:~$ ps -ef|grep test-hid-a ubuntu 4773 3082 0 11:09 pts/3 00:00:00 ./test-hid-a ubuntu 4794 3194 0 11:09 pts/4 00:00:00 grep test-hid-a ubuntu@VM-0-17-ubuntu:~$ pmap -x 4773 4773: ./test-hid-a Address Kbytes RSS Dirty Mode Mapping 000055b2814cd000 4 4 0 r-x-- test-hid-a 000055b2814cd000 0 0 0 r-x-- test-hid-a 000055b2816ce000 4 4 4 r---- test-hid-a 000055b2816ce000 0 0 0 r---- test-hid-a 000055b2816cf000 4 4 4 rw--- test-hid-a 000055b2816cf000 0 0 0 rw--- test-hid-a 000055b282710000 132 4 4 rw--- [ anon ] 000055b282710000 0 0 0 rw--- [ anon ] 00007eff6c989000 1948 1180 0 r-x-- libc-2.27.so 00007eff6c989000 0 0 0 r-x-- libc-2.27.so 00007eff6cb70000 2048 0 0 ----- libc-2.27.so 00007eff6cb70000 0 0 0 ----- libc-2.27.so 00007eff6cd70000 16 16 16 r---- libc-2.27.so 00007eff6cd70000 0 0 0 r---- libc-2.27.so 00007eff6cd74000 8 8 8 rw--- libc-2.27.so 00007eff6cd74000 0 0 0 rw--- libc-2.27.so 00007eff6cd76000 16 12 12 rw--- [ anon ] 00007eff6cd76000 0 0 0 rw--- [ anon ] 00007eff6cd7a000 164 152 0 r-x-- ld-2.27.so 00007eff6cd7a000 0 0 0 r-x-- ld-2.27.so 00007eff6cf97000 8 8 8 rw--- [ anon ] 00007eff6cf97000 0 0 0 rw--- [ anon ] 00007eff6cfa3000 4 4 4 r---- ld-2.27.so 00007eff6cfa3000 0 0 0 r---- ld-2.27.so 00007eff6cfa4000 4 4 4 rw--- ld-2.27.so 00007eff6cfa4000 0 0 0 rw--- ld-2.27.so 00007eff6cfa5000 4 4 4 rw--- [ anon ] 00007eff6cfa5000 0 0 0 rw--- [ anon ] 00007ffdc50e7000 132 8 8 rw--- [ stack ] 00007ffdc50e7000 0 0 0 rw--- [ stack ] 00007ffdc51af000 12 0 0 r---- [ anon ] 00007ffdc51af000 0 0 0 r---- [ anon ] 00007ffdc51b2000 8 4 0 r-x-- [ anon ] 00007ffdc51b2000 0 0 0 r-x-- [ anon ] ffffffffff600000 4 0 0 r-x-- [ anon ] ffffffffff600000 0 0 0 r-x-- [ anon ] ---------------- ------- ------- ------- total kB 4520 1416 76

可以看到,静态调用占用的内存与 源码方式是一样的,这个也能证明静态调用的特点。

3.4 隐性动态调用

将共享库编译成libcalculate.so,然后我们在测试程序中,引用动态库头文件,编译,同时将动态库拷贝到/usr/lib/下,运行,监控如下:

ubuntu@VM-0-17-ubuntu:~$ ps -ef|grep test-hid ubuntu 5433 3082 0 11:13 pts/3 00:00:00 ./test-hid ubuntu 5480 3194 0 11:13 pts/4 00:00:00 grep test-hid ubuntu@VM-0-17-ubuntu:~$ pmap -x 5433 5433: ./test-hid Address Kbytes RSS Dirty Mode Mapping 00005564e6e88000 4 4 0 r-x-- test-hid 00005564e6e88000 0 0 0 r-x-- test-hid 00005564e7088000 4 4 4 r---- test-hid 00005564e7088000 0 0 0 r---- test-hid 00005564e7089000 4 4 4 rw--- test-hid 00005564e7089000 0 0 0 rw--- test-hid 00005564e79d1000 132 4 4 rw--- [ anon ] 00005564e79d1000 0 0 0 rw--- [ anon ] 00007f64bfd05000 1948 1068 0 r-x-- libc-2.27.so 00007f64bfd05000 0 0 0 r-x-- libc-2.27.so 00007f64bfeec000 2048 0 0 ----- libc-2.27.so 00007f64bfeec000 0 0 0 ----- libc-2.27.so 00007f64c00ec000 16 16 16 r---- libc-2.27.so 00007f64c00ec000 0 0 0 r---- libc-2.27.so 00007f64c00f0000 8 8 8 rw--- libc-2.27.so 00007f64c00f0000 0 0 0 rw--- libc-2.27.so 00007f64c00f2000 16 12 12 rw--- [ anon ] 00007f64c00f2000 0 0 0 rw--- [ anon ] 00007f64c00f6000 4 4 0 r-x-- libcalculate.so 00007f64c00f6000 0 0 0 r-x-- libcalculate.so 00007f64c00f7000 2044 0 0 ----- libcalculate.so 00007f64c00f7000 0 0 0 ----- libcalculate.so 00007f64c02f6000 4 4 4 r---- libcalculate.so 00007f64c02f6000 0 0 0 r---- libcalculate.so 00007f64c02f7000 4 4 4 rw--- libcalculate.so 00007f64c02f7000 0 0 0 rw--- libcalculate.so 00007f64c02f8000 164 160 0 r-x-- ld-2.27.so 00007f64c02f8000 0 0 0 r-x-- ld-2.27.so 00007f64c0512000 20 12 12 rw--- [ anon ] 00007f64c0512000 0 0 0 rw--- [ anon ] 00007f64c0521000 4 4 4 r---- ld-2.27.so 00007f64c0521000 0 0 0 r---- ld-2.27.so 00007f64c0522000 4 4 4 rw--- ld-2.27.so 00007f64c0522000 0 0 0 rw--- ld-2.27.so 00007f64c0523000 4 4 4 rw--- [ anon ] 00007f64c0523000 0 0 0 rw--- [ anon ] 00007ffc8b435000 132 12 12 rw--- [ stack ] 00007ffc8b435000 0 0 0 rw--- [ stack ] 00007ffc8b4ef000 12 0 0 r---- [ anon ] 00007ffc8b4ef000 0 0 0 r---- [ anon ] 00007ffc8b4f2000 8 4 0 r-x-- [ anon ] 00007ffc8b4f2000 0 0 0 r-x-- [ anon ] ffffffffff600000 4 0 0 r-x-- [ anon ] ffffffffff600000 0 0 0 r-x-- [ anon ] ---------------- ------- ------- ------- total kB 6588 1332 92

上述监控可以看到,内存使用基本上没有太大变化,不过内存中已经有了 libcalculate.so 了。

3.5 显性动态调用

显性动态调用测试代码如下:

#include #include #include #define LIB_CALCULATE_PATH "./tmp/libcalculate.so" typedef int (*CALC_FUNC)(int, int); typedef void (*CALC_FUNC1)(void); int main(void) { void *handle; char *error; CALC_FUNC calc_func = NULL; CALC_FUNC1 print_func = NULL; printf("start wait 60s...\n"); sleep(60); printf("will return in 20...\n"); handle = dlopen(LIB_CALCULATE_PATH, RTLD_LAZY); if (!handle) { fprintf(stderr, "%s\n", dlerror()); return -1; } dlerror(); *(void **) (&calc_func) = dlsym(handle, "add"); if ((error = dlerror()) != NULL) { fprintf(stderr, "%s\n", error); return -1; } printf("add: %d\n", (*calc_func)(2,7)); print_func = (CALC_FUNC1)dlsym(handle, "print_CA_info"); print_func(); sleep(20); return 0; }

编译、运行、监控如下:

ubuntu@VM-0-17-ubuntu:~$ ps -ef|grep test-obvious ubuntu 6139 3082 0 11:18 pts/3 00:00:00 ./test-obvious ubuntu 6156 3194 0 11:18 pts/4 00:00:00 grep test-obvious ubuntu@VM-0-17-ubuntu:~$ pmap -x 6139 6139: ./test-obvious Address Kbytes RSS Dirty Mode Mapping 00005561450f1000 4 4 0 r-x-- test-obvious 00005561450f1000 0 0 0 r-x-- test-obvious 00005561452f2000 4 4 4 r---- test-obvious 00005561452f2000 0 0 0 r---- test-obvious 00005561452f3000 4 4 4 rw--- test-obvious 00005561452f3000 0 0 0 rw--- test-obvious 00005561459a5000 132 4 4 rw--- [ anon ] 00005561459a5000 0 0 0 rw--- [ anon ] 00007f1c0abc2000 1948 1080 0 r-x-- libc-2.27.so 00007f1c0abc2000 0 0 0 r-x-- libc-2.27.so 00007f1c0ada9000 2048 0 0 ----- libc-2.27.so 00007f1c0ada9000 0 0 0 ----- libc-2.27.so 00007f1c0afa9000 16 16 16 r---- libc-2.27.so 00007f1c0afa9000 0 0 0 r---- libc-2.27.so 00007f1c0afad000 8 8 8 rw--- libc-2.27.so 00007f1c0afad000 0 0 0 rw--- libc-2.27.so 00007f1c0afaf000 16 12 12 rw--- [ anon ] 00007f1c0afaf000 0 0 0 rw--- [ anon ] 00007f1c0afb3000 12 12 0 r-x-- libdl-2.27.so 00007f1c0afb3000 0 0 0 r-x-- libdl-2.27.so 00007f1c0afb6000 2044 0 0 ----- libdl-2.27.so 00007f1c0afb6000 0 0 0 ----- libdl-2.27.so 00007f1c0b1b5000 4 4 4 r---- libdl-2.27.so 00007f1c0b1b5000 0 0 0 r---- libdl-2.27.so 00007f1c0b1b6000 4 4 4 rw--- libdl-2.27.so 00007f1c0b1b6000 0 0 0 rw--- libdl-2.27.so 00007f1c0b1b7000 164 164 0 r-x-- ld-2.27.so 00007f1c0b1b7000 0 0 0 r-x-- ld-2.27.so 00007f1c0b3d1000 20 12 12 rw--- [ anon ] 00007f1c0b3d1000 0 0 0 rw--- [ anon ] 00007f1c0b3e0000 4 4 4 r---- ld-2.27.so 00007f1c0b3e0000 0 0 0 r---- ld-2.27.so 00007f1c0b3e1000 4 4 4 rw--- ld-2.27.so 00007f1c0b3e1000 0 0 0 rw--- ld-2.27.so 00007f1c0b3e2000 4 4 4 rw--- [ anon ] 00007f1c0b3e2000 0 0 0 rw--- [ anon ] 00007fffe6879000 132 16 16 rw--- [ stack ] 00007fffe6879000 0 0 0 rw--- [ stack ] 00007fffe69a7000 12 0 0 r---- [ anon ] 00007fffe69a7000 0 0 0 r---- [ anon ] 00007fffe69aa000 8 4 0 r-x-- [ anon ] 00007fffe69aa000 0 0 0 r-x-- [ anon ] ffffffffff600000 4 0 0 r-x-- [ anon ] ffffffffff600000 0 0 0 r-x-- [ anon ] ---------------- ------- ------- ------- total kB 6596 1360 96 ubuntu@VM-0-17-ubuntu:~$ pmap -x 6139 6139: ./test-obvious Address Kbytes RSS Dirty Mode Mapping 00005561450f1000 4 4 0 r-x-- test-obvious 00005561450f1000 0 0 0 r-x-- test-obvious 00005561452f2000 4 4 4 r---- test-obvious 00005561452f2000 0 0 0 r---- test-obvious 00005561452f3000 4 4 4 rw--- test-obvious 00005561452f3000 0 0 0 rw--- test-obvious 00005561459a5000 132 4 4 rw--- [ anon ] 00005561459a5000 0 0 0 rw--- [ anon ] 00007f1c0a9c0000 4 4 0 r-x-- libcalculate.so 00007f1c0a9c0000 0 0 0 r-x-- libcalculate.so 00007f1c0a9c1000 2044 0 0 ----- libcalculate.so 00007f1c0a9c1000 0 0 0 ----- libcalculate.so 00007f1c0abc0000 4 4 4 r---- libcalculate.so 00007f1c0abc0000 0 0 0 r---- libcalculate.so 00007f1c0abc1000 4 4 4 rw--- libcalculate.so 00007f1c0abc1000 0 0 0 rw--- libcalculate.so 00007f1c0abc2000 1948 1272 0 r-x-- libc-2.27.so 00007f1c0abc2000 0 0 0 r-x-- libc-2.27.so 00007f1c0ada9000 2048 0 0 ----- libc-2.27.so 00007f1c0ada9000 0 0 0 ----- libc-2.27.so 00007f1c0afa9000 16 16 16 r---- libc-2.27.so 00007f1c0afa9000 0 0 0 r---- libc-2.27.so 00007f1c0afad000 8 8 8 rw--- libc-2.27.so 00007f1c0afad000 0 0 0 rw--- libc-2.27.so 00007f1c0afaf000 16 12 12 rw--- [ anon ] 00007f1c0afaf000 0 0 0 rw--- [ anon ] 00007f1c0afb3000 12 12 0 r-x-- libdl-2.27.so 00007f1c0afb3000 0 0 0 r-x-- libdl-2.27.so 00007f1c0afb6000 2044 0 0 ----- libdl-2.27.so 00007f1c0afb6000 0 0 0 ----- libdl-2.27.so 00007f1c0b1b5000 4 4 4 r---- libdl-2.27.so 00007f1c0b1b5000 0 0 0 r---- libdl-2.27.so 00007f1c0b1b6000 4 4 4 rw--- libdl-2.27.so 00007f1c0b1b6000 0 0 0 rw--- libdl-2.27.so 00007f1c0b1b7000 164 164 0 r-x-- ld-2.27.so 00007f1c0b1b7000 0 0 0 r-x-- ld-2.27.so 00007f1c0b3d1000 20 12 12 rw--- [ anon ] 00007f1c0b3d1000 0 0 0 rw--- [ anon ] 00007f1c0b3e0000 4 4 4 r---- ld-2.27.so 00007f1c0b3e0000 0 0 0 r---- ld-2.27.so 00007f1c0b3e1000 4 4 4 rw--- ld-2.27.so 00007f1c0b3e1000 0 0 0 rw--- ld-2.27.so 00007f1c0b3e2000 4 4 4 rw--- [ anon ] 00007f1c0b3e2000 0 0 0 rw--- [ anon ] 00007fffe6879000 132 16 16 rw--- [ stack ] 00007fffe6879000 0 0 0 rw--- [ stack ] 00007fffe69a7000 12 0 0 r---- [ anon ] 00007fffe69a7000 0 0 0 r---- [ anon ] 00007fffe69aa000 8 4 0 r-x-- [ anon ] 00007fffe69aa000 0 0 0 r-x-- [ anon ] ffffffffff600000 4 0 0 r-x-- [ anon ] ffffffffff600000 0 0 0 r-x-- [ anon ] ---------------- ------- ------- ------- total kB 8652 1564 104

上面的监控信息我们可以清楚的看到:

在显性调用中,dlopen之前, libcalculate.so并没有读入到内存中,但是因为使用了插件机制,将libdl-2.27.so 插件库读入内存了,也是因为这个原因,导致内存并没有想象中的那么小。dlopen之后,libcalculate.so 被读入内存中,内存也增加到了1564kb。 3.6 内存对比 方式内存源码1416Kb静态库1416Kb隐性动态库1332显性动态库调用前1360Kb/调用后1564Kb 小结 显性调用更多的是体现在“插件”的思想,使用起来更加灵活,比如大的工程项目中,同样一套代码,提供不一样的功能时,为了节省内存、磁盘容量,可以按需加载。在使用方式上,显性调用相比隐性调用,略复杂,需要增加额外的转换代码,而隐性调用,只需要包含动态库头文件,在代码中,直接调用API即可。在生产程序中,如果对内存或磁盘、启动速度没有严苛的要求,尽量使用隐形调用,方便程序编写和维护。


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有