日期核心版本
架構作者
github
csdn
2017-07-04
linux-4.12
x86lwhuq
linuxmemorystudy
linux記憶體管理
在numa多cpu架構下,每個cpu後面都有掛載本地記憶體,cpu之前通過匯流排連線。每個cpu在訪問當地記憶體的速度都會比訪問遠端記憶體速度快。linux系統下把每個cpu的本地記憶體資源用乙個結點node表示。
pg_data_t的定義在include/linux/mmzone.h#l601
typedef struct pglist_data pg_data_t;
結點管理的記憶體再細分成記憶體域。
typedef struct pglist_data
typedef struct pglist_data pg_data_t;
在每個結點的結構pg_data_t內有乙個指向頁結構page的指標node_mem_map。pg_data_t->node_mem_map指向本結點管理的物理記憶體頁框的第乙個頁框。
typedef struct pglist_data
pg_data_t->node_mem_map的初始化在alloc_node_mem_map中完成,定義在
mm/page_alloc.c#l6096
static void __ref alloc_node_mem_map(struct pglist_data *pgdat)
}
typedef struct pglist_data pg_data_t;
當系統中有超過乙個結點時,核心會維護乙個點陣圖node_states用以提供各個結點的狀態資訊,其定義在
include/linux/nodemask.h#l381
enum node_states ;
結點點陣圖的例項node_states定義在
mm/page_alloc.c#l122, 當某個node處在某個狀態時,對應狀態位的node位就會被置起。
nodemask_t node_states[nr_node_states] __read_mostly = },
#ifndef config_numa
[n_normal_memory] = },
#ifdef config_highmem
[n_high_memory] = },
#endif
#ifdef config_movable_node
[n_memory] = },
#endif
[n_cpu] = },
#endif /* numa */
};export_symbol(node_states);
幾個輔助函式用於設定或清除位域或特定結點中的乙個bit。定義在
include/linux/nodemask.h#l407
static inline int node_state(int node, enum node_states state)
static inline void node_set_state(int node, enum node_states state)
static inline void node_clear_state(int node, enum node_states state)
static inline int num_node_state(enum node_states state)
記憶體結點的例項為node_data[max_numnodes],定義在
arch/x86/mm/numa.c#l26
struct pglist_data *node_data[max_numnodes] __read_mostly;
export_symbol(node_data);
記憶體結點最大數目由max_numnodes決定,定義在include/linux/numa.h#l11
#ifdef config_nodes_shift
#define nodes_shift config_nodes_shift
#else
#define nodes_shift 0
#define max_numnodes (1 << nodes_shift)
#endif
巨集node_data(nid)可以根據node id找到node_data結構例項,定義在
arch/x86/include/asm/mmzone_32.h#l13和
arch/x86/include/asm/mmzone_64.h#l14
#define node_data(nid) (node_data[nid])
巨集first_online_node用於得到第乙個online的node,定義在
include/linux/nodemask.h#l430
#define first_online_node first_node(node_states[n_online])
巨集 first_memory_node得到第乙個有memory的node,定義在
include/linux/nodemask.h#l431
#define first_memory_node first_node(node_states[n_memory])
巨集next_node(n, src)得到某個node state狀態src的下乙個被置起的node id,定義在
include/linux/nodemask.h#l258
#define next_node(n, src) __next_node((n), &(src))
static inline int __next_node(int n, const nodemask_t *srcp)
函式next_online_node得到下乙個online的node,定義在
include/linux/nodemask.h#l432
static inline int next_online_node(int nid)
函式next_memory_node得到下乙個有memory的node,定義在
include/linux/nodemask.h#l436
static inline int next_memory_node(int nid)
巨集for_each_node_state(__node, __state)用來遍歷處於特定狀態的所有結點,定義在
include/linux/nodemask.h#l427
#define for_each_node_state(__node, __state) \
for_each_node_mask((__node), node_states[__state])
巨集for_each_node(node)用來迭代處於n_possible狀態的所有結點,定義在
include/linux/nodemask.h#l507
#define for_each_node(node) for_each_node_state(node, n_possible)
巨集for_each_online_node(node)用來遍歷處於n_online所有結點,定義在
include/linux/nodemask.h#l508
#define for_each_online_node(node) for_each_node_state(node, n_online)
函式first_online_pgdat得到第乙個online的pg_data結構的指標,定義在
mm/mmzone.c#l12
struct pglist_data *first_online_pgdat(void)
函式next_online_pgdat(pgdat)得到下乙個online的pg_data結構的指標,定義在
mm/mmzone.c#l17
struct pglist_data *next_online_pgdat(struct pglist_data *pgdat)
巨集for_each_online_pgdat(pgdat)用來遍歷所有online的pg_data_t結構指標,定義在
include/linux/mmzone.h#l908
#define for_each_online_pgdat(pgdat) \
for (pgdat = first_online_pgdat(); \
pgdat; \
pgdat = next_online_pgdat(pgdat))
C 記憶體管理2
我們都知道c 中有三種建立物件的方法,如下 include using namespace std class a a int main 第一種和第二種沒什麼區別,乙個隱式呼叫,乙個顯式呼叫,兩者都是在程序虛擬位址空間中的棧中分配記憶體,而第三種使用了new,在堆中分配了記憶體,而棧中記憶體的分配和...
OC語法 2 2 記憶體管理 手動記憶體管理2
五 copy語法 這篇建議學過foundation框架之後再學習 本小節知識點 基本用法 1 乙個物件可以使用 copy 或者mutablecopy 方法來建立物件的副本,當我們操作副本的時候不影響原物件 2 copy 需要先實現 nscopying 協議,建立的是不可變副本 如 nsstring,...
總結 OC記憶體管理 2
上篇文章對記憶體管理進行了概括性描述,本篇文章將對retain方法和release方法的具體使用場景做出描述 被遺忘一次,計數器 1 release方法 被遺忘分為兩種 主動遺忘和被動遺忘 方式一 呼叫者有了新物件,故意遺忘掉老物件 示例 乙個person有了新wife void setwife g...