searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

Linux内核中的匿名页(Anonymous Page)

2024-12-11 08:57:52
8
0

在Linux内核中,匿名页(Anonymous Page)指的是没有与具体文件系统中的文件关联的内存页。这种内存通常用于存储动态分配的数据,如进程的堆、栈以及使用mmap创建的匿名内存区域。

设计匿名页的原因

  1. 动态内存分配:许多应用程序在运行时需要动态分配内存,匿名页提供了一种简单的方式来满足这些需求,而无需在文件系统中创建相应的文件。
  2. 内存保护:匿名页允许操作系统为每个进程提供独立的内存空间,保护各个进程之间的内存不被直接访问。
  3. 简化I/O:对于不需要持久存储的内存,匿名页可以减少文件I/O的开销,提高内存访问的效率。

使用场景和作用

  1. 进程堆和栈:大多数应用程序在运行时会使用堆和栈来存储局部变量、对象等,匿名页为这些内存提供了支持。
  2. 共享内存:通过使用shmgetmmap创建的匿名共享内存区域,进程可以有效地进行进程间通信(IPC)。
  3. 内存映射文件:当使用mmap映射一个文件但不希望文件内容影响内存(如执行代码或共享数据时),匿名页可以作为虚拟内存的一部分。
  4. 页面替换:在内存压力大的情况下,匿名页可以被交换到磁盘,以释放内存给其他进程。

总之,匿名页在动态内存管理和进程间通信中起着重要作用,为操作系统提供了灵活且高效的内存使用方式。


这是一个使用匿名页的例子:

#include <stdio.h>
#include <stdlib.h>

int main() {
    // 动态分配内存
    size_t size = 1024 * 1024 * 1024; // 分配1GB
    void *ptr = malloc(size);

    if (ptr == NULL) {
        perror("malloc failed");
        return 1;
    }

    // 使用分配的内存
    for (size_t i = 0; i < size; i++) {
        ((char *)ptr)[i] = 'A'; // 填充内存
    }

    // 打印前10个字节
    printf("First 10 bytes: ");
    for (size_t i = 0; i < 10; i++) {
        printf("%c ", ((char *)ptr)[i]);
    }
    printf("\n");

    // 释放内存
    free(ptr);
    return 0;
}

程序执行之前:

# cat /proc/meminfo 
MemTotal:       395115492 kB
MemFree:        374575448 kB
MemAvailable:   390520104 kB
Buffers:          574264 kB
Cached:         17450828 kB
SwapCached:            0 kB
Active:          2003164 kB
Inactive:       16358148 kB
Active(anon):      13036 kB
Inactive(anon):   365072 kB
Active(file):    1990128 kB
Inactive(file): 15993076 kB
Unevictable:       11188 kB
Mlocked:           11188 kB
SwapTotal:             0 kB
SwapFree:              0 kB
Dirty:                92 kB
Writeback:             0 kB
AnonPages:        309404 kB

程序执行中:

# cat /proc/meminfo 
MemTotal:       395115492 kB
MemFree:        373975116 kB
MemAvailable:   389919816 kB
Buffers:          574300 kB
Cached:         17450832 kB
SwapCached:            0 kB
Active:          2003208 kB
Inactive:       16960956 kB
Active(anon):      13040 kB
Inactive(anon):   967876 kB
Active(file):    1990168 kB
Inactive(file): 15993080 kB
Unevictable:       11188 kB
Mlocked:           11188 kB
SwapTotal:             0 kB
SwapFree:              0 kB
Dirty:                12 kB
Writeback:             0 kB
AnonPages:        923592 kB

通过比较这两份/proc/meminfo的输出,我们可以看到内存使用情况的变化,特别是关于匿名页(Active(anon)Inactive(anon)AnonPages)的部分。

总体内存信息

  • MemTotal: 总内存量未变化,依然是395115492 kB。
  • MemFree: 从374575448 kB减少到373975116 kB,表示空闲内存减少。
  • MemAvailable: 从390520104 kB减少到389919816 kB,表示可用内存也减少。
  • BuffersCached: 这两项变化不大,表明文件系统缓存和缓冲区的使用相对稳定。

具体变化分析

  1. Active(anon):
    • 从13036 kB增加到13040 kB,表示活跃的匿名页略有增加。这通常是由于有新的匿名内存被分配并被使用。
  2. Inactive(anon):
    • 从365072 kB增加到967876 kB,表示闲置的匿名页显著增加。这意味着之前有一些匿名页不再被活动进程使用,因此变得不活跃。这可能是因为某些进程释放了动态分配的内存,或者某些进程终止后其内存被标记为不活跃。
  3. AnonPages:
    • 从309404 kB增加到923592 kB,表示匿名页的总量显著增加。这表明系统在这段时间内分配了大量新的匿名内存。从这里我们可以得知,匿名内存增加了600MB,这与我们实际分配的1GB有区别。

总结

  • 整体内存使用中,虽然空闲和可用内存有所减少,但活跃的匿名页变化不大。
  • 但有相当数量的匿名页变为不活跃,并且AnonPages的数量大幅增加,这表明有新的匿名内存分配(如通过mallocmmap等动态分配方式)。
  • 这可能是因为某些应用程序在这段时间内增加了内存使用(如加载新的数据或对象),或者一些进程使用了新的动态内存。

总体来看,这些变化反映了系统在处理内存请求和动态内存分配时的状态,尤其是与匿名页相关的内存动态变化。

这是一个不使用匿名页的例子:

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <unistd.h>

int main() {
    const char *filename = "example.txt";
    
    // 打开文件
    int fd = open(filename, O_RDONLY);
    if (fd == -1) {
        perror("open failed");
        return 1;
    }

    // 获取文件大小
    off_t filesize = lseek(fd, 0, SEEK_END);
    lseek(fd, 0, SEEK_SET); // 重置文件指针

    // 映射文件到内存
    char *mapped = mmap(NULL, filesize, PROT_READ, MAP_PRIVATE, fd, 0);
    if (mapped == MAP_FAILED) {
        perror("mmap failed");
        close(fd);
        return 1;
    }

    // 使用映射的内容
    printf("File contents:\n");
    write(STDOUT_FILENO, mapped, filesize); // 输出文件内容

    // 解除映射
    if (munmap(mapped, filesize) == -1) {
        perror("munmap failed");
    }

    // 关闭文件
    close(fd);
    return 0;
}

程序执行前:

# cat /proc/meminfo 
MemTotal:       395115492 kB
MemFree:        374571060 kB
MemAvailable:   390518552 kB
Buffers:          576640 kB
Cached:         17451112 kB
SwapCached:            0 kB
Active:          2011892 kB
Inactive:       16351760 kB
Active(anon):      19356 kB
Inactive(anon):   358420 kB
Active(file):    1992536 kB
Inactive(file): 15993340 kB
Unevictable:       11188 kB
Mlocked:           11188 kB
SwapTotal:             0 kB
SwapFree:              0 kB
Dirty:                84 kB
Writeback:             0 kB
AnonPages:        301836 kB

程序执行中:

# cat /proc/meminfo 
MemTotal:       395115492 kB
MemFree:        374571084 kB
MemAvailable:   390518584 kB
Buffers:          576648 kB
Cached:         17451112 kB
SwapCached:            0 kB
Active:          2011904 kB
Inactive:       16352272 kB
Active(anon):      19360 kB
Inactive(anon):   358932 kB
Active(file):    1992544 kB
Inactive(file): 15993340 kB
Unevictable:       11188 kB
Mlocked:           11188 kB
SwapTotal:             0 kB
SwapFree:              0 kB
Dirty:                92 kB
Writeback:             0 kB
AnonPages:        302380 kB

可以看到程序执行前和执行中的匿名内存几乎没有变化。

 

0条评论
0 / 1000
木喳喳
9文章数
1粉丝数
木喳喳
9 文章 | 1 粉丝
原创

Linux内核中的匿名页(Anonymous Page)

2024-12-11 08:57:52
8
0

在Linux内核中,匿名页(Anonymous Page)指的是没有与具体文件系统中的文件关联的内存页。这种内存通常用于存储动态分配的数据,如进程的堆、栈以及使用mmap创建的匿名内存区域。

设计匿名页的原因

  1. 动态内存分配:许多应用程序在运行时需要动态分配内存,匿名页提供了一种简单的方式来满足这些需求,而无需在文件系统中创建相应的文件。
  2. 内存保护:匿名页允许操作系统为每个进程提供独立的内存空间,保护各个进程之间的内存不被直接访问。
  3. 简化I/O:对于不需要持久存储的内存,匿名页可以减少文件I/O的开销,提高内存访问的效率。

使用场景和作用

  1. 进程堆和栈:大多数应用程序在运行时会使用堆和栈来存储局部变量、对象等,匿名页为这些内存提供了支持。
  2. 共享内存:通过使用shmgetmmap创建的匿名共享内存区域,进程可以有效地进行进程间通信(IPC)。
  3. 内存映射文件:当使用mmap映射一个文件但不希望文件内容影响内存(如执行代码或共享数据时),匿名页可以作为虚拟内存的一部分。
  4. 页面替换:在内存压力大的情况下,匿名页可以被交换到磁盘,以释放内存给其他进程。

总之,匿名页在动态内存管理和进程间通信中起着重要作用,为操作系统提供了灵活且高效的内存使用方式。


这是一个使用匿名页的例子:

#include <stdio.h>
#include <stdlib.h>

int main() {
    // 动态分配内存
    size_t size = 1024 * 1024 * 1024; // 分配1GB
    void *ptr = malloc(size);

    if (ptr == NULL) {
        perror("malloc failed");
        return 1;
    }

    // 使用分配的内存
    for (size_t i = 0; i < size; i++) {
        ((char *)ptr)[i] = 'A'; // 填充内存
    }

    // 打印前10个字节
    printf("First 10 bytes: ");
    for (size_t i = 0; i < 10; i++) {
        printf("%c ", ((char *)ptr)[i]);
    }
    printf("\n");

    // 释放内存
    free(ptr);
    return 0;
}

程序执行之前:

# cat /proc/meminfo 
MemTotal:       395115492 kB
MemFree:        374575448 kB
MemAvailable:   390520104 kB
Buffers:          574264 kB
Cached:         17450828 kB
SwapCached:            0 kB
Active:          2003164 kB
Inactive:       16358148 kB
Active(anon):      13036 kB
Inactive(anon):   365072 kB
Active(file):    1990128 kB
Inactive(file): 15993076 kB
Unevictable:       11188 kB
Mlocked:           11188 kB
SwapTotal:             0 kB
SwapFree:              0 kB
Dirty:                92 kB
Writeback:             0 kB
AnonPages:        309404 kB

程序执行中:

# cat /proc/meminfo 
MemTotal:       395115492 kB
MemFree:        373975116 kB
MemAvailable:   389919816 kB
Buffers:          574300 kB
Cached:         17450832 kB
SwapCached:            0 kB
Active:          2003208 kB
Inactive:       16960956 kB
Active(anon):      13040 kB
Inactive(anon):   967876 kB
Active(file):    1990168 kB
Inactive(file): 15993080 kB
Unevictable:       11188 kB
Mlocked:           11188 kB
SwapTotal:             0 kB
SwapFree:              0 kB
Dirty:                12 kB
Writeback:             0 kB
AnonPages:        923592 kB

通过比较这两份/proc/meminfo的输出,我们可以看到内存使用情况的变化,特别是关于匿名页(Active(anon)Inactive(anon)AnonPages)的部分。

总体内存信息

  • MemTotal: 总内存量未变化,依然是395115492 kB。
  • MemFree: 从374575448 kB减少到373975116 kB,表示空闲内存减少。
  • MemAvailable: 从390520104 kB减少到389919816 kB,表示可用内存也减少。
  • BuffersCached: 这两项变化不大,表明文件系统缓存和缓冲区的使用相对稳定。

具体变化分析

  1. Active(anon):
    • 从13036 kB增加到13040 kB,表示活跃的匿名页略有增加。这通常是由于有新的匿名内存被分配并被使用。
  2. Inactive(anon):
    • 从365072 kB增加到967876 kB,表示闲置的匿名页显著增加。这意味着之前有一些匿名页不再被活动进程使用,因此变得不活跃。这可能是因为某些进程释放了动态分配的内存,或者某些进程终止后其内存被标记为不活跃。
  3. AnonPages:
    • 从309404 kB增加到923592 kB,表示匿名页的总量显著增加。这表明系统在这段时间内分配了大量新的匿名内存。从这里我们可以得知,匿名内存增加了600MB,这与我们实际分配的1GB有区别。

总结

  • 整体内存使用中,虽然空闲和可用内存有所减少,但活跃的匿名页变化不大。
  • 但有相当数量的匿名页变为不活跃,并且AnonPages的数量大幅增加,这表明有新的匿名内存分配(如通过mallocmmap等动态分配方式)。
  • 这可能是因为某些应用程序在这段时间内增加了内存使用(如加载新的数据或对象),或者一些进程使用了新的动态内存。

总体来看,这些变化反映了系统在处理内存请求和动态内存分配时的状态,尤其是与匿名页相关的内存动态变化。

这是一个不使用匿名页的例子:

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <unistd.h>

int main() {
    const char *filename = "example.txt";
    
    // 打开文件
    int fd = open(filename, O_RDONLY);
    if (fd == -1) {
        perror("open failed");
        return 1;
    }

    // 获取文件大小
    off_t filesize = lseek(fd, 0, SEEK_END);
    lseek(fd, 0, SEEK_SET); // 重置文件指针

    // 映射文件到内存
    char *mapped = mmap(NULL, filesize, PROT_READ, MAP_PRIVATE, fd, 0);
    if (mapped == MAP_FAILED) {
        perror("mmap failed");
        close(fd);
        return 1;
    }

    // 使用映射的内容
    printf("File contents:\n");
    write(STDOUT_FILENO, mapped, filesize); // 输出文件内容

    // 解除映射
    if (munmap(mapped, filesize) == -1) {
        perror("munmap failed");
    }

    // 关闭文件
    close(fd);
    return 0;
}

程序执行前:

# cat /proc/meminfo 
MemTotal:       395115492 kB
MemFree:        374571060 kB
MemAvailable:   390518552 kB
Buffers:          576640 kB
Cached:         17451112 kB
SwapCached:            0 kB
Active:          2011892 kB
Inactive:       16351760 kB
Active(anon):      19356 kB
Inactive(anon):   358420 kB
Active(file):    1992536 kB
Inactive(file): 15993340 kB
Unevictable:       11188 kB
Mlocked:           11188 kB
SwapTotal:             0 kB
SwapFree:              0 kB
Dirty:                84 kB
Writeback:             0 kB
AnonPages:        301836 kB

程序执行中:

# cat /proc/meminfo 
MemTotal:       395115492 kB
MemFree:        374571084 kB
MemAvailable:   390518584 kB
Buffers:          576648 kB
Cached:         17451112 kB
SwapCached:            0 kB
Active:          2011904 kB
Inactive:       16352272 kB
Active(anon):      19360 kB
Inactive(anon):   358932 kB
Active(file):    1992544 kB
Inactive(file): 15993340 kB
Unevictable:       11188 kB
Mlocked:           11188 kB
SwapTotal:             0 kB
SwapFree:              0 kB
Dirty:                92 kB
Writeback:             0 kB
AnonPages:        302380 kB

可以看到程序执行前和执行中的匿名内存几乎没有变化。

 

文章来自个人专栏
现代操作系统原理及实现
9 文章 | 1 订阅
0条评论
0 / 1000
请输入你的评论
0
0