Linux系统相关的基础问题(空间、内存、库、链接、环境变量)

文章目录

    • 一、用户空间与内核空间
      • 1、用户空间与内核空间
      • 2、用户态与内核态
    • 二、物理内存(地址)与虚拟内存(地址)
      • 1、早期的内存实现
      • (1)在早期的计算机中,运行一个程序的特点:
      • (2)在早期的内存实现方式中出现的问题:
      • 2、虚拟地址技术
      • (1)虚拟地址的特点:
      • 3、物理内存
      • 4、物理内存与虚拟内存的关系
    • 三、静态库与共享库(动态库)
      • 1、静态库
      • 2、共享库(动态库)
      • 3、共享库(动态库)与静态库的比较
    • 四、硬链接与软链接
      • 1、什么是链接?
      • 2、链接有什么用
      • 3、硬链接
      • 4、软链接
      • 5、硬链接与软链接的区别
    • 五、环境变量

一、用户空间与内核空间

1、用户空间与内核空间

  4G的进程地址空间被人为的分为两个部分–用户空间与内核空间。用户空间从0到3G(0xc0000000),内核空间占据3G到4G。用户进程通常情况下只能访问用户空间的虚拟地址,不能访问内核空间的虚拟地址。例外情况只有用户进程进行系统调用(代表用户进程在内核态执行)等时刻可以访问到内核空间。
Linux系统相关的基础问题(空间、内存、库、链接、环境变量)_第1张图片

2、用户态与内核态

  内核态: CPU可以访问内存所有数据, 包括外围设备, 例如硬盘, 网卡. CPU也可以将自己从一个程序切换到另一个程序。
  用户态: 只能受限的访问内存, 且不允许访问外围设备. 占用CPU的能力被剥夺, CPU资源可以被其他程序获取。

  为什么要有用户态和内核态:

  由于需要限制不同的程序之间的访问能力, 防止他们获取别的程序的内存数据, 或者获取外围设备的数据, 并发送到网络, CPU划分出两个权限等级 – 用户态 和 内核态。所有用户程序都是运行在用户态的, 但是有时候程序确实需要做一些内核态的事情, 例如从硬盘读取数据, 或者从键盘获取输入等. 而唯一可以做这些事情的就是操作系统, 所以此时程序就需要先操作系统请求以程序的名义来执行这些操作.。

二、物理内存(地址)与虚拟内存(地址)

1、早期的内存实现

(1)在早期的计算机中,运行一个程序的特点:

  • 把这些程序全都装入内存;
  • 程序都是直接运行在内存上的,也就是说程序中访问的内存地址都是实际的物理内存地址。

(2)在早期的内存实现方式中出现的问题:

  • 当计算 机同时运行多个程序时,必须保证这些程序用到的内存总量要小于计算机实际物理内存的大小;
  • 进程地址空间不隔离,进程间可以相互修改数据;
  • 内存使用率低。运行一个进程,必须在内存中为它分配实际进程大小的空间(不管当前这些空间是否都会用到);
  • 程序运行的地址不确定。分配内存时,只是单纯的从内存空间找一个足够满足进程要求的空间,所以进程运行的地址具有随机性。

2、虚拟地址技术

  为了解决上面的问题,一些大牛们就提出了传说中的虚地址技术。即:在用户进程和实际的物理内存之间加一个中间层(虚拟地址),让用户进程只能访问虚拟地址,并且把虚拟地址物理地址转换的实现交给操作系统

(1)虚拟地址的特点:

  • OS会为每个进程分配一个4G大小的虚拟地址空间,且每个进程都有3G的用户空间和1G的内核空间。但最后这1G的内核空间中的内容对于不同进程来说是一样的(之所以是4G大小,是因为在32位操作系统中,一个指针的大小是4btyes,所以能访问的地址空间就是0x00000000~0xFFFFFFFF == 4G);
  • 这4G的虚拟地址空间是操作系统虚拟出来的,并不是真实存在的,每次访问内存空间的某个地址,都需要把地址翻译为实际物理内存地址。
  • 每个进程只能访问自己的虚拟地址,无法访问别的进程的虚拟地址;
  • 虽然每个进程的虚拟地址都有4G大小,但并不是这4G的地址都可以由用户任意使用。
    Linux系统相关的基础问题(空间、内存、库、链接、环境变量)_第2张图片

3、物理内存

  当打开程序时,系统会将这些程序加载到物理内存上。
Linux系统相关的基础问题(空间、内存、库、链接、环境变量)_第3张图片

4、物理内存与虚拟内存的关系

  当运行程序过多,物理内存不够用时,系统会将一部分硬盘空间当内存使用,这部分空间就是虚拟内存(主要是解决物理内存稀缺问题)。系统为每个进程所分配的4GB虚拟地址空间(32位系统),用来存放进程的虚拟地址,进程直接操作虚拟地址空间,读写数据时,才给它调拨物理存储器(通过MMU(内存管理单元)将虚拟地址映射到物理内存地址)。

三、静态库与共享库(动态库)

  本质上来说库是一种可执行代码的二进制形式,可以被操作系统载入内存执行。由于Windows和linux本质不同,因此二者库的二进制是不兼容的。库有两种:静态库(.a、.lib)和共享库也称动态库(.so、.dll)。

1、静态库

  静态库将所有相关的目标文件打包成为一个单独的文件,即静态库文件,其缺省扩展名是 .a 。链接静态库就是将库中被调用的代码复制到调用模块中。静态库占用空间大,库中代码一旦修改必须重新链接。使用静态库的代码在运行时无需依赖库,且执行效率高

  静态库命名规范,必须是lib[your_library_name].a:lib为前缀,中间是静态库名,扩展名为.a。例如:libadd.a。

2、共享库(动态库)

  共享库和静态库最大的不同就是,链接共享库并不需要将库中被调用的代码复制到调用模块中,相反被嵌入到调用模块中的仅仅是被调用代码在共享库中的相对地址。如果共享库中的代码同时为多个进程所用,共享库的实例在整个内存空间中仅需一份,这正是共享的意义所在。共享库占用空间小,即使修改了库中的代码,只要接口保持不变,无需重新链接。使用共享库的代码在运行时需要依赖库,执行效率略低。而共享库的缺省扩展名是: .so。
  共享库命名规范,必须是lib[your_library_name].so:lib为前缀,中间是共享库名,扩展名为 .so
例如:libadd.so。

3、共享库(动态库)与静态库的比较

(1)静态库在程序编译时会被连接到目标代码中,程序运行时将不再需要该静态库。当程序与静态库连接时,库中目标文件所含的所有将被程序使用的函数的机器码被copy到最终的可执行文件中。这就会导致最终生成的可执行代码量相对变多,相当于编译器将代码补充完整了,这样运行起来相对就快些。不过会有个缺点: 占用磁盘和内存空间。静态库会被添加到和它连接的每个程序中,而且这些程序运行时,都会被加载到内存中,无形中又多消耗了更多的内存空间。

(2)动态库在程序编译时并不会被连接到目标代码中,而是在程序运行是才被载入,因此在程序运行时还需要动态库存在。与共享库连接的可执行文件只包含它需要的函数的引用表,而不是所有的函数代码,只有在程序执行时,那些需要的函数代码才被拷贝到内存中。这样就使可执行文件比较小,节省磁盘空间,更进一步,操作系统使用虚拟内存,使得一份共享库驻留在内存中被多个程序使用,也同时节约了内存。不过由于运行时要去链接库会花费一定的时间,执行速度相对会慢一些。

(3)总的来说静态库是牺牲了空间效率,换取了时间效率,共享库是牺牲了时间效率换取了空间效率,没有好与坏的区别,只看具体需要了

(4)另外,一个程序编好后,有时需要做一些修改和优化,如果我们要修改的刚好是库函数的话,在接口不变的前提下,使用共享库的程序只需要将共享库重新编译就可以了,而使用静态库的程序则需要将静态库重新编译好后,将程序再重新编译一遍

四、硬链接与软链接

1、什么是链接?

  链接简单说实际上是一种文件共享的方式,是 POSIX 中的概念,主流文件系统都支持链接文件。

2、链接有什么用

  你可以将链接简单地理解为 Windows 中常见的快捷方式(或是 OS X 中的替身),Linux 中常用它来解决一些库版本的问题,通常也会将一些目录层次较深的文件链接到一个更易访问的目录中。在这些用途上,我们通常会使用到软链接(也称符号链接)。

3、硬链接

  硬链接本质上是一个指针,指向目标文件的索引节点。一个目录项只能对应一个索引节点,而一个索引节点可以对应多个目录项。因此,一个目录项只能有一个链接,而一个索引节点可以有多个链接。

4、软链接

  软链接是指一个文件的间接指针,其文件内容主要是用于记录文件的存储路径。软链接提供了一个指向目标文件的快捷途径。

5、硬链接与软链接的区别

  硬连接的作用是允许一个文件拥有多个有效路径名,这样用户就可以建立硬连接到重要文件,以防止“误删”的功能。而建立软链接就是建立了一个新文件。当访问链接文件时,系统就会发现他是个链接文件,它读取链接文件找到真正要访问的文件

五、环境变量

  环境变量一般是指在操作系统中用来指定操作系统运行环境的一些参数,如:临时文件夹位置和系统文件夹位置等。环境变量时在操作系统中一个具有特定名字的对象,它包含了一个或者多个应用程序所将使用的信息。

  linux是一个多用户的操作系统,每个用户登录系统之后,都会有一个专用的运行环境。通常每个用户默认的环境都是相同的。这个默认的环境实际上就是一组环境变量的定义,用户可以对自己的运行环境进行定制,其方法就是修改相应的系统环境变量。

修改和查看环境变量的指令:

//echo:查看单个环境变量
# echo $HOME
/root

// env:查看所有环境变量
# env

// export:设置一个新的环境变量 (临时的,重启后消失)
# export HELLO="hello"
# echo $HELLO
hello

// unset:清除环境变量
# unset HELLO

// 添加环境变量
vim /etc/profile
添加 export PATH="/opt/hisi-linux/x86-arm/arm-hisiv300-linux/target/bin:$PATH"
执行 source /etc/profile

参考:https://www.cnblogs.com/zemliu/p/3695503.html
https://www.cnblogs.com/wuchanming/p/4465188.html
https://blog.csdn.net/qq_29350001/article/details/62217915

你可能感兴趣的:(#,Linux基础知识,用户空间与内和空间,环境变量,硬链接与软链接,物理内存与虚拟内存,静态库与动态库)