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

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/目录,否则程序无法执行程序开始执行,不管是否用到动态库功能,都会将动态库读到内存中不会额外调用插件库
显性调用不需要引用动态库头文件,但是需要引用<dlfcn.h>不一定,如果程序不会执行到动态库功能,则不需要拷贝,即便使用,也可以使用绝对路径来使用,不需要拷贝到/usr/lib/目录下只有程序执行到dlopen时,才会将动态库读入内存会额外调用linux插件库,来支持显性调用

3. 测试

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

3.1 场景

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

#include <stdio.h>
#include <stdarg.h>
#include <unistd.h>


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 <stdio.h>
#include <unistd.h>
#include <dlfcn.h>

#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即可。
  • 在生产程序中,如果对内存或磁盘、启动速度没有严苛的要求,尽量使用隐形调用,方便程序编写和维护。

(523条消息) 深入分析linux下 动态库的显性调用(dlopen)和隐性调用区别_猪哥-嵌入式的博客-CSDN博客_linux动态库调用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值