something about memory management经典!

本文详细介绍了Linux内核中的内存管理机制,包括物理页面的基本管理单位struct page结构体及其字段含义,不同内存区域(如DMA区、常规区及高内存区)的作用与划分依据,并列举了常用的内存分配函数及应用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

高端内存相关? 

Pages
//内核把物理页面当做内存管理的基本单元 


The kernel represents every physical page on the system with a struct page structure. This structure is defined in <linux/mm.h>:
//内核用struct page 结构体 代表每个物理页面
struct page {
        page_flags_t          flags;
        atomic_t              _count;
        atomic_t              _mapcount;
        unsigned long         private;
        struct address_space  *mapping;
        pgoff_t               index;
        struct list_head      lru;
        void                  *virtual;
};

主要域的解析:
FLAGS:
The flags field stores the status of the page. Such flags include whether the page is dirty or whether it is locked in memory. Bit flags represent the various values, so at least 32 different flags are simultaneously available. The flag values are defined in <linux/page-flags.h>.
_COUNT:
The _count field stores the usage count of the pagethat is, how many references there are to this page.
VIRTUAL:
The virtual field is the page's virtual address. Normally, this is simply the address of the page in virtual memory. Some memory (called high memory) is not permanently mapped in the kernel's address space. In that case, this field is NULL and the page must be dynamically mapped when needed

 

Zones
Because of hardware limitations, the kernel cannot treat all pages as identical. Some pages, because of their physical address in memory, cannot be used for certain tasks. Because of this limitation, the kernel divides pages into different zones. The kernel uses the zones to group pages of similar properties.
there are three memory zones in Linux:

ZONE_DMA This zone contains pages that are capable of undergoing DMA.

ZONE_NORMAL This zone contains normal, regularly mapped, pages.

ZONE_HIGHMEM This zone contains "high memory," which are pages not permanently mapped into the kernel's address space.

These zones are defined in <linux/mmzone.h>.

 

一些分配内存的函数!!!

在下面的函数中 :

page structure 即返回的是直接指向物理内存中的内存空间的指针

logical address 即返回的是指向虚拟内存空间的内存的指针

注意!:

This function works the same as alloc_pages(), except that it directly returns the logical address of the first requested page. Because the pages are contiguous, the other pages simply follow from the first.

 

 

Table 11.2. Low-Level Page Allocations Methods

Flag

Description

alloc_page(gfp_mask)

Allocate a single page and return a pointer to its page structure

alloc_pages(gfp_mask, order)

Allocate 2order pages and return a pointer to the first page's page structure

__get_free_page(gfp_mask)

Allocate a single page and return a pointer to its logical address

__get_free_pages(gfp_mask, order)

Allocate 2order pages and return a pointer to the first page's logical address

get_zeroed_page(gfp_mask)

Allocate a single page, zero its contents, and return a pointer to its logical address

 

 

 

分配与释放内存空间!!!
unsigned long page;

page = __get_free_pages(GFP_KERNEL, 3);
if (!page) {
        /* insufficient memory: you must handle this error! */
        return ENOMEM;
}

/* 'page' is now the address of the first of eight contiguous pages ... */

free_pages(page, 3);

/*
 * our pages are now freed and we should no
 * longer access the address stored in 'page'
 */

The function is declared in <linux/slab.h>:

void * kmalloc(size_t size, int flags)

参数FLAG的使用!!!!

GFP_KERNEL 可能会引起阻塞,使reached!所以不能用在..........

GFP_AROMIC就解决了这个问题

Table 11.7. Which Flag to Use When

Situation

Solution

Process context, can sleep

Use GFP_KERNEL

Process context, cannot sleep

Use GFP_ATOMIC, or perform your allocations with GFP_KERNEL at an earlier or later point when you can sleep

Interrupt handler

Use GFP_ATOMIC

Softirq

Use GFP_ATOMIC

Tasklet

Use GFP_ATOMIC

Need DMA-able memory, can sleep

Use (GFP_DMA | GFP_KERNEL)

Need DMA-able memory, cannot sleep

Use (GFP_DMA | GFP_ATOMIC), or perform your allocation at an earlier point when you can sleep

.

char *buf;

buf = kmalloc(BUF_SIZE, GFP_ATOMIC);
if (!buf)
        /* error allocting memory ! */


Later, when you no longer need the memory, do not forget to free it:

kfree(buf);
VMALLOC()
The kmalloc() function guarantees that the pages are physically 
contiguous (and virtually contiguous).
 The vmalloc() function only ensures that the pages are contiguous within 
the virtual address space.
一般硬件要求的则是连续的物理地址!!!!
For the most part, only hardware devices require physically 
contiguous memory allocations.
 
/**********************************************************

下面的红字是TLB的解释:
The TLB (translation lookaside buffer) is a hardware cache used by
 most architectures to cache the mapping of virtual addresses to physical 
addresses. This greatly improves the performance of the system, 
because most memory access is done via virtual addressing.
 
般在内核代码中,都是使用

 

kmalloc申请的内存空间物理地址和虚拟地址都是连续的!

vmalloc申请的内存空间虚拟地址连续,而物理地址不是连续的!

 

必须建立一个页表的入口(page table entries),而且,物理内存需要一页一页的(因为不是连续的!)映射到虚拟内存空间。这样与一整块物理内存直接映射相比,TLB要做多的多的工作。所以vmalloc()函数开销大 ,所以,它一般用做于申请一大块的内存空间

kmalloc() ,因为使用vmalloc() 的开销比它大。 为了使物理内存中不连续的页在虚拟内存中是连续的,

 
于上面文字对应的英语正文如下:
most kernel code uses kmalloc() and not vmalloc() 
to obtain memory. Primarily, this is for performance. 
The vmalloc() function, to make nonphysically contiguous 
pages contiguous in the virtual address space, must specifically set up 
the page table entries. Worse, pages obtained via vmalloc() must be mapped by
 their individual pages (because they are not physically contiguous), 
which results in much greater TLB[4] thrashing than you see when directly 
mapped memory is used. Because of these concerns, vmalloc() is used only 
when absolutely necessary typically, to obtain very large regions of memory. 
For example, when modules are dynamically inserted into the kernel, 
they are loaded into memory created via vmalloc().
一个运用vmalloc函数的例子: 当动态插入驱动模块时!!!!!!!!!
使用例子:
char *buf;

buf = vmalloc(16 * PAGE_SIZE); /* get 16 pages */
if (!buf)
        /* error! failed to allocate memory */

/*
 * buf now points to at least a 16*PAGE_SIZE bytes
 * of virtually contiguous block of memory
 */

After you are finished with the memory, make sure to free it by using

vfree(buf);
内容概要:文章基于4A架构(业务架构、应用架构、数据架构、技术架构),对SAP的成本中心和利润中心进行了详细对比分析。业务架构上,成本中心是成本控制的责任单元,负责成本归集与控制,而利润中心是利润创造的独立实体,负责收入、成本和利润的核算。应用架构方面,两者都依托于SAP的CO模块,但功能有所区分,如成本中心侧重于成本要素归集和预算管理,利润中心则关注内部交易核算和获利能力分析。数据架构中,成本中心与利润中心存在多对一的关系,交易数据通过成本归集、分摊和利润计算流程联动。技术架构依赖SAP S/4HANA的内存计算和ABAP技术,支持实时核算与跨系统集成。总结来看,成本中心和利润中心在4A架构下相互关联,共同为企业提供精细化管理和决策支持。 适合人群:从事企业财务管理、成本控制或利润核算的专业人员,以及对SAP系统有一定了解的企业信息化管理人员。 使用场景及目标:①帮助企业理解成本中心和利润中心在4A架构下的运作机制;②指导企业在实施SAP系统时合理配置成本中心和利润中心,优化业务流程;③提升企业对成本和利润的精细化管理水平,支持业务决策。 其他说明:文章不仅阐述了理论概念,还提供了具体的应用场景和技术实现方式,有助于读者全面理解并应用于实际工作中。
03-29
In the provided references, there is no explicit mention of `numRef`. However, based on common usage within programming and software development contexts, `numRef` could represent several concepts depending on its specific implementation: ### Possible Interpretations 1. **Numerical Reference**: In some cases, `numRef` might stand for "numerical reference," which refers to an identifier or pointer associated with numerical data such as counters, indices, or unique identifiers tied to numbers[^2]. For example: ```java int numRef = 42; System.out.println(numRef); // Outputs: 42 ``` 2. **Number of References**: Another plausible meaning involves tracking how many times something has been referenced in memory management systems or garbage collection mechanisms. This concept aligns closely with reference counting techniques used by certain languages like Python or C++ when managing dynamic allocations. 3. **Custom Variable Name**: It may simply serve as shorthand notation created specifically within user-defined codebases where developers choose variable names according to their project requirements without adhering strictly to standard nomenclature conventions. Without additional information regarding exact source material mentioning 'numRef', these remain speculative interpretations derived logically through general knowledge about coding practices rather than direct evidence found among given citations above. ```python class ExampleClass: def __init__(self): self.numRef = 0 def increment_num_ref(self): self.numRef += 1 example_instance = ExampleClass() print(example_instance.numRef) # Output before incrementation: 0 example_instance.increment_num_ref() print(example_instance.numRef) # After first increment: 1 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值