『 Linux 』动态库的加载

文章目录

    • 动静态库的区别
    • 动态库-共享库
    • 动态库的加载
      • 动态库的管理
    • 总结


动静态库的区别

请添加图片描述

  • 动态库(Dynamic Libraries)

    • 链接方式

      动态链接,程序在运行时(而不是在编译时)与动态库链接;

      操作系统负责加载动态库文件;

    • 文件大小

      使用动态库的应用程序通常其可执行文件大小更小;

      因为库代码在运行时将会从单独的库文件进行加载;

    • 内存使用

      如果多个程序同时使用一个动态库,则该库在内存中只需要加载一次,节省系统资源;

    • 更新和发布

      更新动态库较为方便;

      只需替换动态库文件本身即可而不需要重新编译使用它的程序;

      使得动态库适用于需要频繁更新或者维护的软件组件;

  • 静态库(Static Libraries)

    • 链接方式

      静态链接,程序在编译时与静态库进行链接,静态库的代码数据被复制到最终的可执行文件中;

    • 文件大小

      使用静态库的应用程序通常会有更大的可执行文件,因为其静态库的代码和数据将被集中到应用程序中;

    • 内存使用

      每个使用静态库的应用程序都会有自己的库代码副本;

      在内存中可能会导致重复冗余的内容;

    • 更新和发布

      更新你需要使用到静态库的组件时必须重新编译整个程序;

      这意味着静态库适合不经常更新的库,或者用户希望应用程序是完全独立且不依赖外部其他库文件时;


动态库-共享库

请添加图片描述

与静态库不同,动态库在进程运行时要被加载;

一般情况下常见的动态库会被所有的可执行程序动态链接,故动态库又被称为共享库;

这意味着动态库在系统中加载后将会被所有的进程共享;

磁盘中的文件需要被管理,动态库是文件也需要被管理;

当一个可执行程序需要加载这个动态库时将会以特定的路径将动态库加载至内存;

若是一个可执行程序依赖于多个动态库时将会把这些依赖的动态库同样加载至内存当中;

这些被加载至内存的动态库将以 先描述再组织 的方式被操作系统进行管理,而若是有其他进程需要调用这些动态库时只需要间接在操作系统的管理下找到这个动态库并与其他进程进行共用即可;

动态库的共享属性主要围绕以下几点:

  • 资源共享

    动态库允许其代码在物理内存中至有一份拷贝而可以被多个正在运行的进程所共享;

    这种方式与静态库形成对比,静态库的代码被复制到每个使用它的可执行文件当中,导致相同的代码在内存中形成冗余;

    动态库通过减少重复的代码加载有效减少了系统的内存占用从而提高内存使用效率;

  • 动态链接

    程序在运行时加载动态库被称为动态链接,类比C++中的多态;

    这意味可执行程序将在运行时寻找并链接其依赖的动态库;

    它们可以在运行时共享这个库的同一个实例而不需要在每个程序中进行加载;

  • 跨进程共享

    操作系统负责管理动态库的链接和加载;

    当第一个程序请求加载特定的动态库时操作系统将会把这个动态库加载进内存并对其管理;

    此后如果有其他进程也依赖这个动态库时将直接在操作系统的管理下找到这个库并进行链接;

  • 减少磁盘和内存使用

    动态库通过其共享属性减少系统中重复的代码存储和加载从而介绍磁盘空间和运行时的内存占用;


动态库的加载

请添加图片描述

  • 可执行程序的执行

    用户请求执行一个可执行文件;

    当操作系统接收到执行请求时将会从文件系统重读取指定的可执行文件;

    这个文件包含了程序的代码数据以及其动态库的依赖信息;

  • 进程的创建

    • 创建进程控制块task_struct

      当程序被执行时其将加载进内存并成为进程;

      操作系统将会为新的进程分配一个task_struct结构体用于存储进程的所有信息;

      包括进程状态,PID,进程地址空间指针,页表指针等等;

    • 分配进程地址空间

      操作系统将会为进程分配一个虚拟地址空间并根据可执行文件的内容初始化代码段和数据段;

  • 动态库的加载

    加载器解析可执行文件中的动态库依赖信息,并根据依赖信息在磁盘上查找对应的动态库文件;

    这个过程可能会参考LD_LIBRARY_PATH环境变量,/etc/ld.so.cache文件以及标准路径如/lib64//usr/lib;

    找到动态库文件后,加载器将会把动态库的内容加载进物理内存;

    如果涉及多个进程依赖同一个动态库,操作系统将会让这些进程共享内存中的同一份动态库以节省内存;

    具体的方法是在当前被管理的动态库中寻找新进程所依赖的动态库是否已经在当前物理内存中留有副本,若是有则直接进行链接从而减少I/O次数;

    当动态库被加载进内存时同样需要被页表进行映射以保证其安全性;

    一般情况下动态库将会被映射至每个依赖该动态库的进程地址空间中用户空间的共享区当中;

    若是某个进程需要对其中的内容进行写入操作时将发生写时拷贝,将会为这个进程单独拷贝一份私有的内容为这个进程服务;

  • 进程的运行

    加载器对动态库进行重定位处理,解析程序对动态库中符号的引用以确保这些引用指向正确的内存地址;

    当所有依赖的动态库被加载完成后,操作系统将开始执行进程的代码,进程也将进入运行状态;

  • 进程的管理

    操作系统将通过task_struct管理进程的执行,根据调度策略在不同进程间切换以确保系统资源的合理分配使用;


动态库的管理

请添加图片描述

操作系统通过间接的方式了解当前系统中所有已经被加载的库与未被加载的库;

动态库的管理同样是采用 “先描述后组织” 的方式进行;

在操作系统中存在一个结构体为link_map;

这个结构体用来表示每个加载的动态库(共享库);

其结构体可能包含库的内存地址,库的名称,指向库的动态段的指针等;

struct link_map {
  /* 库的加载地址 */
  ElfW(Addr) l_addr;

  /* 库的路径名 */
  char* l_name;

  /* 指向库的动态段(.dynamic节)的指针 */
  ElfW(Dyn)* l_ld;

  /* 链表中的下一个和上一个link_map结构的指针 */
  struct link_map *l_next, *l_prev;
};

总结

请添加图片描述

动态库和静态库是软件开发中两种主要的代码库链接方式;

其中动态库在程序运行时被加载并允许代码在物理内存中只有一份拷贝而被多个进程共享从而减少系统资源的消耗;

相比之下,静态库在程序编译时被整合进可执行文件;

导致每个程序都包含了一份库的副本,增加了程序的大小和内存占用;

动态库的管理依赖于操作系统中的结构体,如link_map;

它记录了库的加载地址,名称等信息,确保动态链接和库间依赖关系的正确处理;

通过高效地管理和加载动态库,系统能够提高内存使用效率,简化库的更新过程,并支持跨进程的库共享;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/705663.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

missing authentication credentials for REST request

1、报错截图 2、解决办法 将elasticsearch的elasticsearch.yml的 xpack.security.enabled: true 改为 xpack.security.enabled: false

vba学习系列(5)--指定区域指定字符串计数

系列文章目录 文章目录 系列文章目录前言一、需求背景二、vba自定义函数1.引入库 总结 前言 一、需求背景 想知道所有客诉项目里面什么项目最多,出现过多少次。 二、vba自定义函数 1.引入库 引用: CountCharInRange(区域,“字符串”) Function CountCh…

光伏电站阵列式冲击波声压光伏驱鸟器

光伏电站内鸟群的聚集可不是一件好事,鸟类排泄物,因其粘度大、具有腐蚀性的特点,一旦堆积在太阳能板上,会严重影响光伏电站的发电效率。长期积累的鸟粪不仅难以清洗,还可能引发组件的热斑效应,严重时甚至可…

Bean基础配置

黑马程序员SSM 文章目录 一、Bean基础配置二、bean别名配置2.1 ban的别名配置2.2 注意事项 三、Bean作用范围配置3.1 Bean作用范围3.2 bean作用范围说明 一、Bean基础配置 二、bean别名配置 2.1 ban的别名配置 2.2 注意事项 获取bean无论是通过id还是name获取,如果…

.NET MAUI Sqlite程序应用-数据库配置(一)

项目名称:Ownership(权籍信息采集) 一、安装 NuGet 包 安装 sqlite-net-pcl 安装 SQLitePCLRawEx.bundle_green 二、创建多个表及相关字段 Models\OwnershipItem.cs using SQLite;namespace Ownership.Models {public class fa_rural_base//基础数据…

ArcGIS Pro SDK (三)Addin控件 1 按钮类

ArcGIS Pro SDK (一)Addin控件 目录 ArcGIS Pro SDK (一)Addin控件1 Addin控件2 ArcGIS Pro 按钮2.1 添加控件2.2 Code 3 ArcGIS Pro 按钮面板3.1 添加控件3.2 Code 4 ArcGIS Pro 菜单4.1 添加控件4.2 Code 5 ArcGIS Pro 分割按钮…

如何从零训练多模态大模型(预训练方向)

节前,我们星球组织了一场算法岗技术&面试讨论会,邀请了一些互联网大厂朋友、参加社招和校招面试的同学. 针对算法岗技术趋势、大模型落地项目经验分享、新手如何入门算法岗、该如何准备、面试常考点分享等热门话题进行了深入的讨论。 汇总合集&…

所爱隔山海,上海婚恋交友app开发,我奔向你

每每讲到婚恋,就有感叹“难”的声音,在婚恋市场上,到处充斥者“难”的声音,更有胜者,甚至发出了“难于上青天”的感叹。在婚恋市场蹉跎浮沉的青年俊女们,越挫越勇,向着爱的呼唤,一次…

Java工具-实现无损png转换jpg格式

目录 1、背景说明 2、通过代码实现格式转换 3、无损转化 4、说明 读取 PNG 图像: 创建空的 JPG 图像: 绘制 PNG 图像到 JPG 图像: 设置 JPG 图片压缩质量: 写入 JPG 文件并关闭流: 5、jpg转png 1、背景说明 …

Opencv图像梯度计算

Opencv图像梯度计算 Sobel算子 可以理解为是做边缘检测的一种方法。 首先说明自己对图像梯度的简单理解:简单理解就是图像的颜色发生变化的边界区域在X方向和Y方向上的梯度值 Gx Gy 而Gx和Gy处的梯度的计算—使用下面的公式来进行计算。 G x [ − 1 0 1 − 2 0 …

计算机网络(5) ARP协议

什么是ARP 地址解析协议,即ARP(Address Resolution Protocol),是根据IP地址获取物理地址的一个TCP/IP协议。主机发送信息时将包含目标IP地址的ARP请求广播到局域网络上的所有主机,并接收返回消息,以此确定…

【MySQL】mysql中常见的内置函数(日期、字符串、数学函数)

文章目录 案例表日期函数字符串函数数学函数其他函数 案例表 emp students 表 exam_result 表 日期函数 注意current_time和now的区别 案例一: 创建一张表用来记录生日,表结构如下 添加日期: insert tmp (birthday) values (2003-01-3…

香港CN2线路回国加速CDN介绍

随着互联网的迅猛发展,跨境数据传输的需求日益增加。尤其对于中国内地用户来说,访问海外网站和应用时,常常会面临网络延迟高、加载速度慢的问题。为了优化这一体验,香港 CN2 线路回国加速 CDN 成为了许多企业和个人的首选解决方案…

从Log4j和Fastjson RCE漏洞认识jndi注入

文章目录 前言JNDI注入基础介绍靶场搭建漏洞验证注入工具 log4j RCE漏洞分析漏洞靶场检测工具补丁绕过 Fastjson RCE漏洞分析漏洞靶场检测工具补丁绕过 总结 前言 接着前文的学习《Java反序列化漏洞与URLDNS利用链分析》,想了解为什么 Fastjson 反序列化漏洞的利用…

Java中的方法重写与重载

在Java编程语言中,方法重写(Override)和方法重载(Overload)是实现代码多态性的两种基本方式。它们允许程序员以多种方式使用相同的方法名,增加了程序的可读性和可重用性,但它们的应用场景和规则…

Nginx+KeepAlived高可用负载均衡集群的部署

目录 一.KeepAlived补充知识 1.一个合格的群集应该具备的特点 2.健康检查(探针)常用的工作方式 3.相关面试问题 问题1 问题2 二.Keepealived脑裂现象 1.现象 2.原因 硬件原因 运用配置原因 3.解决 4.预防 方法1 方法2 方法3 方法4 三.…

【Spine学习04】之让角色动起来

1、切换左上角模式:设置改为动画 2、选择两个手臂的大臂节点 3、打开勾选自动关键帧按钮 4、开始K帧: Space空格可以快捷查看小黄人所有关键帧

英语翻译人工翻译优势

在全球化的时代,跨文化交流至关重要,而翻译则是连接不同语言和文化的重要桥梁。尽管近年来人工智能翻译取得了显著进展,但人工翻译的需求仍然无可替代,尤其是在专业和技术翻译领域。下面从专业角度阐述人工翻译相较于人工智能翻译…

python如何终止程序运行

方法1:采用sys.exit(0),正常终止程序,从图中可以看到,程序终止后shell运行不受影响。 方法2:采用os._exit(0)关闭整个shell,从图中看到,调用sys._exit(0)后整个shell都重启了(RESTAR…

[c++刷题]贪心算法.N01

题目如上: 首先通过经验分析,要用最少的减半次数,使得数组总和减少至一半以上,那么第一反应就是每次都挑数组中最大的数据去减半,这样可以是每次数组总和值减少程度最大化。 代码思路:利用大根堆去找数据中的最大值,…