free的含义究竟是什么?

今天要聊的是linux的free命令,它输出的是内存相关的信息。该命令看似简单,但它所涉及到的一些内存信息经常被误解,所以有必要澄清。

在开发和运维中,我们不仅需要关注CPU资源的消耗情况,还需要关注内存资源的消耗情况,这就必须涉及到free命令,本文将进行实战讲解。

我的云服务器内存简介

我买了一台老东家的云服务器,每年三四百块钱,基本参数如下:

图片

可以看到,内存1G,即1024M. 当我用free命令查看时,结果如下:

ubuntu@VM-0-15-ubuntu:~$ free -wh              total        used        free      shared     buffers       cache   availableMem:           864M        403M         79M         20M         60M        321M        253MSwap:            0B          0B          0Bubuntu@VM-0-15-ubuntu:~$

我买的内存明明是1G, 怎么total才864M呢?

原因是:服务器启动时,会初始化相关设备,会占用内存。而且在linux内核启动时,也会占用一部分内存。那个total 864M是指能被应用程序使用的内存。

如果要看最原始的内存,可用dmidecode命令,看到最大可能的内存是1G(所有内存插槽之和),我的云服务器实际只有1个内存条,这个内存条刚好是1024M.

所以,这台云服务器的总实际物理内存就是1024M:

ubuntu@VM-0-15-ubuntu:~$ sudo dmidecode -t memory # dmidecode 3.0Getting SMBIOS data from sysfs.SMBIOS 2.4 present.
Handle 0x1000, DMI type 16, 15 bytesPhysical Memory Array        Location: Other        Use: System Memory        Error Correction Type: Multi-bit ECC        Maximum Capacity: 1 GB        Error Information Handle: Not Provided        Number Of Devices: 1
Handle 0x1100, DMI type 17, 21 bytesMemory Device        Array Handle: 0x1000        Error Information Handle: 0x0F01        Total Width: 64 bits        Data Width: 64 bits        Size: 1024 MB        Form Factor: DIMM        Set: None        Locator: DIMM 0        Bank Locator: Not Specified        Type: RAM        Type Detail: None
ubuntu@VM-0-15-ubuntu:~$

新版linux的free命令

我注意到, 跟几年前相比,free命令展示的内容和含义有变化。直接来看新版linux的free命令介绍:​​​​​​​

 free   displays the total amount of free and used physical and swap memory in the system, as well as the buffers       and caches used by the kernel. The information is gathered by parsing /proc/meminfo. The displayed columns are:
       total  Total installed memory (MemTotal and SwapTotal in /proc/meminfo)
       used   Used memory (calculated as total - free - buffers - cache)
       free   Unused memory (MemFree and SwapFree in /proc/meminfo)
       shared Memory used (mostly) by tmpfs (Shmem in /proc/meminfo, available on kernels 2.6.32, displayed as zero if              not available)
       buffers              Memory used by kernel buffers (Buffers in /proc/meminfo)
       cache  Memory used by the page cache and slabs (Cached and Slab in /proc/meminfo)
       buff/cache              Sum of buffers and cache
       available              Estimation  of  how much memory is available for starting new applications, without swapping. Unlike the              data provided by the cache or free fields, this field takes into account page cache and  also  that  not              all reclaimable memory slabs will be reclaimed due to items being in use (MemAvailable in /proc/meminfo,              available on kernels 3.14, emulated on kernels 2.6.27+, otherwise the same as free)

可见,free命令从/proc/meminfo获取内存相关信息。而且,有如下关系式:

图片

   

buffers/cache的含义

那么,应用程序和linux操作系统会怎样看待buffers/cache呢?如下图:

图片

在旧版linux中,free命令的结果把buffers/cache归纳到used中。可见,这是站在linux视角的(如下图片是另外一台服务器):

图片

然而,在新版linux中,free命令的结果没有把buffers/cache归纳到used中。可见,这是站在应用程序角度的,如下:​​​​​​​

ubuntu@VM-0-15-ubuntu:~$ free -wh              total        used        free      shared     buffers       cache   availableMem:           864M        403M         79M         20M         60M        321M        253MSwap:            0B          0B          0Bubuntu@VM-0-15-ubuntu:~$

      

所以,在新版linux free命令的结果中,有如下关系式:

total = used + free + buffers + cache

       

站在应用程序的角度,可用内存为:free加buffers/cache之和。然而,实际上只有部分buffers/cache能被应用程序使用,所以一般会有:

available < free + buffers + cache

顺便说一下,在后续的叙述中,我们都是针对新版linux的free命令。

内存消耗的程序验证

我们用程序来验证一下内存的消耗过程(不考虑虚拟内存):​​​​​​​

#include <stdlib.h>#include <stdio.h>#include <string.h>#include <unistd.h>
int main() {    int mb = 0;    char* buffer;
    while((buffer=malloc(1024 * 1024 * 10)) != NULL)     {        memset(buffer, 0, 1024 * 1024 * 10);        mb += 10;        printf("Allocated %d MB\n", mb);        sleep(1);    }
    return 0;}

        

运行程序,可以看到free被不断消耗, available也随之变化:

图片

free的值被消耗完毕后,buffers和cache开始出场了,承担起了被消耗的重任。但是,要注意,并不是所有的buffers和cache都能被消耗殆尽的。

所以,最后进程出现OOM(Out Of Memory)时,cache还有几十M,  而available几乎没有了,如下图所示:

图片

我们看到进程被kill了:

图片

dmesg OOM信息如下:

图片

虚拟内存消耗的程序验证

linux真的这么弱吗?申请290M内存后就扛不住了?简直笑话。

来看free命令结果的Swap信息,可以看到,都是0:

​​​​​​​

ubuntu@VM-0-15-ubuntu:~$ free -wh                          total        used        free      shared     buffers       cache  availableMem:         864M        449M        234M         20M        8.1M        171M        238MSwap:          0B          0B          0B

也就是说,没有开启linux系统的虚拟内存。好的,那我们来开启2G的虚拟内存,如下:

​​​​​​​

ubuntu@VM-0-15-ubuntu:~$ free -wm              total        used        free      shared     buffers       cache   availableMem:            864         439         240          20          10         174         246Swap:          2047           0        2047

       

然后,我们来运行程序,并观察内存消耗。可以看到,最开始消耗的是available内存:

图片

当available内存消耗到一定程度后,才开始使用虚拟内存:

图片

        

当虚拟内存使用完毕后,实在没办法,又开始去消耗available内存,而当available内存被耗尽后,进程被OOM机制给kill了,然后各内存被释放出来:

图片

         

可以看到,进程申请了2G多的内存后才被kill:

图片

       

dmesg OOM信息如下:

图片

结合上述实验,我们可以得知:

  • free接近0时,别紧张。

  • available接近0时,有问题。

  • OOM时,有问题。

生产环境的线上的服务器,有的开启了虚拟内存,有的没有开启虚拟内存。

我刚看了一台线上服务器,没有开启虚拟内存,其内存插槽共144个,每个32G, 故总共支持4608G的内存。

该服务器实际插了4个内存条,故总实际物理内存是128G,除系统占用的内存外,留给应用程序的总内存是125G,available内存是109G, 这内存真是够多的啊:

taoge:~$ sudo dmidecode -t memory | grep GB        Maximum Capacity: 4608 GB        Size: 32 GB        Size: 32 GB        Size: 32 GB        Size: 32 GBtaoge:~$ free -wh              total        used        free      shared     buffers       cache   availableMem:           125G         20G        7.0G        1.3G        369M         97G        109GSwap:            0B          0B          0B

到此为止,我们对linux free命令和各种内存有了更清晰的认识,下次就不会再犯迷糊了。

<think>好的,我现在需要回答用户关于C语言中free()函数的作用及使用方法的问题。首先,我要确保自己正确理解free()的功能。根据引用[1]和[4],free()用于释放由malloc分配的内存,这样内存可以重新被系统使用。但要注意的是,free之后指针本身的值不变,所以需要手动设为NULL,避免野指针的问题。 接下来,用户可能想知道具体的使用步骤。我需要分步骤说明,比如先分配内存,使用后释放,并将指针置空。同时,得提到常见错误,比如重复释放、释放栈内存等,这些在引用[2]和[4]中有涉及,比如alloca分配的是栈内存,不能用free释放,否则会导致错误。 另外,用户可能对为什么需要free感到疑惑,这里需要解释内存泄漏的问题,如果不释放,程序持续运行会耗尽内存。引用[1]提到动态内存分配按需申请,使用后释放,这点很重要。 还要注意使用方法的示例代码是否正确。比如,malloc后检查指针是否为NULL,free之后立即置NULL,这些都是良好的编程习惯,避免悬空指针。 可能的相关问题需要考虑用户可能遇到的疑惑,比如free后内存是否立即被回收,或者为什么有时候free后还能访问数据。这时候需要解释操作系统内存管理的机制,释放后内存可能仍然可访问,但属于未定义行为,应该避免。 最后,根据用户提供的引用,确保引用的正确应用,比如引用[4]中的例子说明free后指针的值不变,需要手动设置NULL,这需要明确提到。 总结回答结构:先解释作用,再详细步骤,注意事项,常见错误,最后示例代码和相关问题。确保覆盖所有关键点,并且引用正确的资料支持。</think>### C语言中free()函数的作用及使用方法 #### 一、free()函数的作用 `free()`函数用于**释放由`malloc()`、`calloc()`或`realloc()`动态分配的内存空间**。其核心作用是将内存归还给操作系统,以便其他程序或后续代码复用[^1]。 - **释放的含义**: 释放后,该内存区域不再属于当前程序,操作系统可重新分配。但指针变量本身的值不会自动变为`NULL`,仍指向原地址(称为“悬空指针”),直接访问可能导致未定义行为[^4]。 - **必要性**: 若未及时释放动态内存,可能导致**内存泄漏**,长期运行会耗尽系统资源。 #### 二、使用方法 1. **基本流程** ```c int *ptr = (int*)malloc(10 * sizeof(int)); // 分配内存 if (ptr == NULL) { // 处理分配失败 } // 使用内存... free(ptr); // 释放内存 ptr = NULL; // 防止悬空指针 ``` 2. **注意事项** - **仅释放动态内存**:`free()`只能用于释放堆内存(由`malloc`等分配),不可释放栈内存(如局部变量)或未分配的内存。 - **禁止重复释放**:对同一指针多次调用`free()`会导致程序崩溃。 - **匹配使用**:`malloc`与`free`需成对出现,且避免混用`alloca()`(栈内存分配函数)[^2]。 3. **常见错误示例** ```c int arr[10]; free(arr); // 错误!arr是栈内存,不可用free释放 int *p = (int*)malloc(100); free(p); free(p); // 错误!重复释放已释放的指针 ``` #### 三、为什么需要手动置NULL? 释放内存后,指针仍保留原地址值,若后续误用可能导致数据损坏。例如: ```c free(ptr); if (ptr != NULL) { *ptr = 10; // 危险!ptr指向的内存已释放 } ``` 通过`ptr = NULL`可明确标记指针失效,避免悬空指针问题[^4]。 #### 四、扩展问题 1. **释放后的内存是否会被立即回收?** 不一定,操作系统可能延迟处理。但程序**无权再访问**该内存区域,否则属于未定义行为。 2. **`free()`如何知道要释放多大的内存?** `malloc`在分配时会记录内存块大小(通常存储在头部元数据中),`free()`通过该信息确定释放范围。 --- ### 相关问题 1. 动态内存分配与静态内存分配的区别是什么? 2. 如何检测C程序中的内存泄漏? 3. `calloc()`和`malloc()`在功能上有何异同? --- 通过合理使用`free()`,可以有效管理程序内存,提升系统资源利用率[^1][^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值