第七章 系统信息与系统资源(7.6-END)

7.6 申请堆内存

        在操作系统下,内存资源是由操作系统进行管理、分配的,当应用程序想要内存时(这里指的是堆内存),可以向操作系统申请内存,然后使用内存;当不再需要时,将申请的内存释放、归还给操作系统;在许多的应用程序当中,往往都会有这种需求,譬如为一些数据结构动态分配/释放内存空间。

7.6.1 在堆上分配内存:malloc 和 free

        虽然依靠终止进程来自动释放内存对大多数程序来说是可以接受的,但最好能够在程序中显式调用free()释放内存,首先其一,显式调用 free()能使程序具有更好的可读性和可维护性;其二,对于很多程序来说,申请的内存并不是在程序的生命周期中一直需要,大多数情况下,都是根据代码需求动态申请、释放的,如果申请的内存对程序来说已经不再需要了,那么就已经把它释放、归还给操作系统,如果持续占用,将会导致内存泄漏,也就是人们常说的“你的程序在吃内存”!

7.6.2 在堆上分配内存的其它方法

用 calloc()分配内存   

       calloc()函数用来动态地分配内存空间并初始化为 0。
        calloc()与 malloc()的一个重要区别是:calloc()在动态分配完内存后,自动初始化该内存空间为零,而malloc()不初始化,里边数据是未知的垃圾数据。

/* 使用 calloc 申请内存 */
base = (int *)calloc(argc - 1, sizeof(int));

7.6.3 分配对其内存

       C 函数库中还提供了一系列在堆上分配对齐内存的函数,对齐内存在某些应用场合非常有必要,常用于分配对其内存的库函数有:posix_memalign()、aligned_alloc()、memalign()、valloc()、pvalloc()。

#include <stdlib.h>
int posix_memalign(void **memptr, size_t alignment, size_t size);
void *aligned_alloc(size_t alignment, size_t size);
void *valloc(size_t size);

#include <malloc.h>
void *memalign(size_t alignment, size_t size);
void *pvalloc(size_t size);

        前面介绍的 malloc()、calloc()分配内存返回的地址其实也是对齐的,但是它俩的对齐都是固定的,并且对其的字节边界比较小,譬如在 32 位系统中,通常是以 8 字节为边界进行对其,
        在 64 位系统中是以 16 字节进行对其。如果想实现更大字节的对齐,则需要使用本小节介绍的函数。

posix_memalign()函数

        posix_memalign()函数用于在堆上分配 size 个字节大小的对齐内存空间,将*memptr 指向分配的空间,分配的内存地址将是 alignment 的整数倍。参数 alignment 表示对齐数,alignment 必须是 2 的幂次方(譬如 2^4、2^8 等),同时也要是 sizeof(void *)的整数倍,对 32位系统 说,sizeof(void *)等于4,如果是 64 位系统 sizeof(void *)等于 8。

#include <stdlib.h>
int posix_memalign(void **memptr, size_t alignment, size_t size);

函数参数和返回值含义如下:
    memptr:void **类型的指针,内存申请成功后会将分配的内存地址存放在*memptr 中。
    alignment:设置内存对齐的字节数,alignment 必须是 2 的幂次方(譬如 2^4、2^5、2^8 等),同时也
              要是 sizeof(void *)的整数倍。
    size:设置分配的内存大小,以字节为单位,如果参数 size 等于 0,那么*memptr 中的值是 NULL。
返回值:
    成功将返回 0;
    失败返回非 0 值。
/* 申请内存: 256 字节对齐 */
ret = posix_memalign((void **)&base, 256, 1024);

aligned_alloc()函数

aligned_alloc()函数用于分配 size 个字节大小的内存空间,返回指向该空间的指针。

#include<stdlib.h>
void *aligned_alloc(size_t alignment, size_t size);

函数参数:
    alignment:用于设置对齐字节大小,alignment 必须是 2 的幂次方(譬如 2^4、2^5、2^8 等)。
    size:设置分配的内存大小,以字节为单位。参数 size 必须是参数 alignment 的整数倍。
返回值:
    成功将返回内存空间的指针,内存空间的起始地址是参数 alignment 的整数倍;
    失败返回 NULL。
/* 申请内存: 256 字节对齐 */
base = (int *)aligned_alloc(256, 256 * 4);

memalign()函数

        memalign()与 aligned_alloc()参数是一样的,它们之间的区别在于:对于参数 size 必须是参数 alignment的整数倍这个限制条件,memalign()并没有这个限制条件。
        memalign()函数已经过时了,并不提倡使用

/* 申请内存: 256 字节对齐 */
base = (int *)memalign(256, 1024);

valloc()函数

        valloc()分配 size 个字节大小的内存空间,返回指向该内存空间的指针,内存空间的地址是页大小
(pagesize)的倍数。valloc()与 memalign()类似,只不过 valloc()函数内部实现中,使用了页大小作为对齐的长度,在程序当中,可以通过系统调用 getpagesize()来获取内存的页大小。        

        valloc()函数已经过时了,并不提倡使用!

/* 申请内存: 1024 个字节 */
base = (int *)valloc(1024);

7.7 proc 文件系统

        proc 文件系统是一个虚拟文件系统,它以文件系统的方式为应用层访问系统内核数据提供了接口,用户和应用程序可以通过 proc 文件系统得到系统信息和进程相关信息,对 proc 文件系统的读写作为与内核进行通信的一种手段。
        但是与普通文件不同的是,proc 文件系统是动态创建的,文件本身并不存在于磁盘当中、只存在于内存当中,与 devfs 一样,都被称为虚拟文件系统。

        最初构建 proc 文件系统是为了提供有关系统中进程相关的信息,但是由于这个文件系统非常有用,因此内核中的很多信息也开始使用它来报告,或启用动态运行时配置。内核构建 proc 虚拟文件系统,它会将内核运行时的一些关键数据信息以文件的方式呈现在 proc 文件系统下的一些特定文件中,这样相当于将一些不可见的内核中的数据结构以可视化的方式呈现给应用层。

        proc 文件系统挂载在系统的/proc 目录下,对于内核开发者(譬如驱动开发工程师)来说,proc 文件系统给了开发者一种调试内核的方法:通过查看/proc/xxx 文件来获取到内核特定数据结构的值,在添加了新功能前后进行对比,就可以判断此功能所产生的影响是否合理。
        /proc 目录下中包含了一些目录和虚拟文件:

         /proc 目录下有很多以数字命名的文件夹,譬如 100038、2299、98560,这些数字对应的其实就
是一个一个的进程 PID 号,每一个进程在内核中都会存在一个编号,通过此编号来区分不同的进程,这个编号就是 PID 号,关于 PID、以及进程相关的信息将会在后面章节内容中向大家介绍.

        /proc 目录下除了文件夹之外,还有很多的虚拟文件,譬如 buddyinfo、cgroups、cmdline、version 等等,不同的文件记录了不同信息,关于这些文件记录的信息和意思如下:
        ⚫ cmdline:内核启动参数;
        ⚫ cpuinfo:CPU 相关信息;
        ⚫ iomem:IO 设备的内存使用情况;
        ⚫ interrupts:显示被占用的中断号和占用者相关的信息;
        ⚫ ioports:IO 端口的使用情况;
        ⚫ kcore:系统物理内存映像,不可读取;
        ⚫ loadavg:系统平均负载;
        ⚫ meminfo:物理内存和交换分区使用情况;
        ⚫ modules:加载的模块列表;
        ⚫ mounts:挂载的文件系统列表;
        ⚫ partitions:系统识别的分区表;
        ⚫ swaps:交换分区的利用情况;
        ⚫ version:内核版本信息;
        ⚫ uptime:系统运行时间;

7.7.1  proc 文件系统的使用

        proc 文件系统的使用就是去读取/proc 目录下的这些文件,获取文件中记录的信息,可以直接使用 cat 命令读取,也可以在应用程序中调用 open()打开、然后再使用 read()函数读取。

使用 cat 命令读取

        在 Linux 系统下直接使用 cat 命令查看/proc 目录下的虚拟文件,譬如"cat /proc/version"查看内核版本相关信息。

        

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值