Linux内存管理

一、内存基础

1、内存的种类 – SRAM,DRAM,SDRAM,DDR SDRAM

Static RAM(静态随机存取内存)是保持数据存储的最简单的形式。Dynamic RAM(动态随机存取内存)是一种需要定时重置的内存,之所以需要这样做是因为电荷会从RAM细胞中“泄漏”出去。写操作可恢复电荷,刷新操作则需要一个定时器和一些电容来存储电荷。 SDRAM (synchronous dynamic RAM)是DRAM的进化版本,具有更高的带宽和更低的延迟。DDR SDRAM (double data rate SDRAM) 使用更复杂的信号路线,在一个时钟周期内传输更多的数据。

2、内存物理分区 – 根据内存大小自动分为几个物理分区

3、内存虚拟分区 – 操作系统通过将主存分成小块来提供更高的内存管理

二、内存管理

1、进程和虚拟地址

/**
 * 用于访问主物理内存的页表在页表所在的页中进行到原始形式和物理形式之间转换的逻辑地址计算工具
 */
#define virt_to_phys(virt)                 (__pa(virt))

/**
 * 通过计算出查找真正的物理地址的单元的索引,从而找到虚拟地址对应的物理地址
 * @param[in] dir 目录指针
 * @param[in] address 虚拟地址
 * @return 对应的物理地址指针
 */
#define PTE_ADDR(hi, lo)                    ((pte_t *)((w32)PTE_BASE + (((hi) << PAGE_DIR_SHIFT) | ((lo) <> 2))
#define pte_offset_virt_to_phys(pdir, address) \
    (*(pte_t **)(&pdir[PTE_INDEX(address)]) + ((address & (PAGE_SIZE - 1)) >> 2))

2、物理内存和虚拟内存

3、内存中断和锁定 – 内核不适用于虚拟内存分页,但可以锁定数据以保持coherency

三、内存分配和释放

1、一般内存池、缓冲区链表和内存碎片

2、内核内存配置和释放 – 调用kmalloc和kfree

/**
 * 分配内核中的内存
 * flags:GFP_KERNEL/fatal_signals_pending
 */
#define kmalloc_(size, flags, align)                                             \
({  void *__kmalloc_result;                                                       \
    BugOn(in_interrupt());                                                        \
    __kmalloc_result = mem_kmalloc(size, flags, align);                            \
    if (unlikely(!__kmalloc_result)) {                                             \
        show_low_mem();                                                             \
        panic("KMALLOC FAILED size %d\n", (int)(size));                              \
    }                                                                               \
    __kmalloc_result;                                                               \
})

/**
 * 释放内核内存
 */
#define kfree_(addr) mem_kfree(addr)

3、内存碎片整理技术 – 使用压缩和紧缩分区管理策略来减少内存碎片

四、内存映射

1、内存管理单元

/**
 * @file memory.h
 * @brief 内存管理单元
 */

#include "pt.h"

struct mm_struct_tag;

/**
 * 页表
 */
typedef struct page_map_contents_tag {
        /**
         * 在上下文中启用页表,该上下文由paging_init()调用生成。所有我们真正关心的页帧都是在初始化上下文时创建的
         */
        pt_t *pt_root;
        int user_pdir_idx;
        /**
         * 首先,我们为一个进程保留单独的页表
         * mm是一个进程上下文的表示
         */
        struct mm_struct_tag *owner;
} pmc_t;

/**
 * 物理页
 */
typedef struct pmem_contents_tag {
        /**
         * 指向内存中该物理页在内存中的位置的指针
         */
        u32 *virt;
        /**
         * 引用计数,表示有多少用户或内核空间块正在使用该页
         */
        u32 usage_count;
} ppc_t;

/**
 * 内存管理单元
 */
typedef struct memory_map_contents_tag {
        /**
         * 整个机器的总物理内存(KBs),在启动时静态分配
         */
        u32 phys_mem_bytes;
        /**
         * 物理页数
         */
        u32 num_phys_pages;
        /**
         * 所有物理页的数组,每个pg和PgMap存储指向其他pmem_contents_struct和page_map_contents_struct结构的指针,用于向新的内存映射添加额外的页
         */
        ppc_t *ppc;
        pmc_t *pmc;
        /**
         * 当前的物理页数,以enable_paging()被调用时初始化为num_phys_pages,然后在每次分配新物理页时减少
         */
        u32 available_phys_pages;
} mmc_t;

2、分页和段式内存管理

3、用户态和内核态的内存访问权限 – 运行用户程序时,访问虚拟地址

五、内存监测和优化

1、监视内存使用情况 – 使用各种工具和技术来掌握内存使用情况,如top,free和vmstat等

2、内存优化 – 避免内存泄漏、碎片以及使用内存和缓存的过度

3、第三方工具 – 针对内存监测和优化的各种第三方工具

原创文章,作者:QKGSA,如若转载,请注明出处:https://www.506064.com/n/373012.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
QKGSAQKGSA
上一篇 2025-04-25 15:26
下一篇 2025-04-25 15:26

相关推荐

  • 如何在Linux中添加用户并修改配置文件

    本文将从多个方面详细介绍在Linux系统下如何添加新用户并修改配置文件 一、添加新用户 在Linux系统下创建新用户非常简单,只需使用adduser命令即可。使用以下命令添加新用户…

    编程 2025-04-27
  • 如何解决linux jar包 invalid or corrupt jarfile问题

    对于许多开发人员和系统管理员在Linux环境下使用Java开发过程中遇到的一个常见的问题是 invalid or corrupt jarfile(无效或损坏的jar文件)错误。当您…

    编程 2025-04-27
  • 在Linux上安装JRE并配置环境变量

    本文将从以下几个方面为您详细阐述如何在Linux系统上,通过自己账户安装JRE,并且配置环境变量。 一、安装JRE 在进行安装前,我们需要下载JRE的安装包并解压,可以从官方网站下…

    编程 2025-04-27
  • GTKAM:Linux下的照片管理器

    GTKAM是用于Linux操作系统的一款照片管理器,它支持多种相机及存储设备,并提供了一系列强大的工具,让用户可以方便地浏览、管理、编辑和导出照片。本文将从多个方面对GTKAM进行…

    编程 2025-04-27
  • Linux sync详解

    一、sync概述 sync是Linux中一个非常重要的命令,它可以将文件系统缓存中的内容,强制写入磁盘中。在执行sync之前,所有的文件系统更新将不会立即写入磁盘,而是先缓存在内存…

    编程 2025-04-25
  • Linux修改文件名命令详解

    在Linux系统中,修改文件名是一个很常见的操作。Linux提供了多种方式来修改文件名,这篇文章将介绍Linux修改文件名的详细操作。 一、mv命令 mv命令是Linux下的常用命…

    编程 2025-04-25
  • Linux网络连接激活失败原因及解决方法

    一、网卡驱动问题 1、缺少网卡驱动 若使用新的网卡,需要安装对应网卡驱动,否则会导致网络连接激活失败。可通过以下命令查看当前系统中是否存在网卡驱动: lsmod | grep et…

    编程 2025-04-25
  • 如何在Windows/Linux/MacOS下安装Python

    如果你对Python安装一无所知,本文将从多个方面对Python在Windows/Linux/MacOS下的安装做出详细阐述,为初学者提供帮助。 一、Windows下Python的…

    编程 2025-04-25
  • Linux Redis 重启

    一、概述 Redis 是一款高性能的 NoSQL 数据库,常用于各种应用场景的数据缓存、消息队列、实时数据分析等等。在使用 Redis 过程中,如果出现了某些问题,有时候只需要重启…

    编程 2025-04-25
  • Linux防火墙配置详解

    一、iptables基本介绍 iptables是一个重要的Linux内核中网络安全系统,通过设置iptables规则,可以对进入和离开Linux服务器的数据进行过滤。 iptabl…

    编程 2025-04-25

发表回复

登录后才能评论