Linux在記憶體管理上,存在一個問題,那就是在系統運行很長一段時間后,物理記憶體中的碎片會越來越多,
1. 記憶體碎片整理
1.1 什么是記憶體碎片呢?
記憶體碎片分為兩種,一種是記憶體頁中的碎片,被稱為內部碎片;另一種是空閑分散的記憶體頁,湊不齊一個組物理地址連續的空閑記憶體頁,就沒辦法分配了,這些散落的記憶體頁被稱為外部碎片,

1.2 內核引入的反碎片技術
- 2.6.23 引入成塊回收,3.5版本后廢除,被碎片整理程式取而代之
- 2.6.33 引入虛擬可移動區域
其中,不管是成塊回識訓是碎片整理,它們都是在碎片之后進行處理,而這往往對系統性能是有損耗的,尤其是回收熱頁的時候,而虛擬可移動區域不同,這是一種預防碎片產生的技術,
1.3 反碎片的作業原理
內核從2.6.24開始引入反碎片技術,試圖從最開始就盡可能的防止碎片的產生,它根據頁的可移動性將可分配頁分為以下三種不同的型別
- 不可移動頁,比如核心內核分配的大多記憶體
- 可回收頁,不能移動,但可以洗掉,
- 可移動頁,可以隨意移動,如用戶空間的頁,移動之后,需要更新頁表項,
導致碎片的原因就是不可移動的頁插在很多連續頁組之后,導致其他空閑頁不能用,而頁加入可移動性之后,就可解決這個問題,
2. 虛擬可移動區域
可移動區域(ZONE_MOVABLE)是一個抽象的記憶體區域,它將物理記憶體分為兩個區域,一個區域用于放置不可移動的頁,另一個區域用于放置可移動的頁,這樣不可移動的頁就不能插在移動區域造成碎片了,
那么如何確定兩個區域的大小呢?
- kernelcore引數用于指定不可移動分配的記憶體數量,指定值保存在required_kernelcore中,
- movablecore引數用于指定可移動分配的記憶體數量,計算值存在required_kernelcore中,
如果兩個引數都設定,那么required_kernelcore = max(指定值,計算值),
原始碼如下
// mm\page_alloc.c
...
static unsigned long __meminitdata arch_zone_lowest_possible_pfn[MAX_NR_ZONES];
static unsigned long __meminitdata arch_zone_highest_possible_pfn[MAX_NR_ZONES];
static unsigned long __initdata required_kernelcore;
static unsigned long __initdata required_movablecore;
static unsigned long __meminitdata zone_movable_pfn[MAX_NUMNODES];
...
/*
* kernelcore=size sets the amount of memory for use for allocations that
* cannot be reclaimed or migrated.
*/
static int __init cmdline_parse_kernelcore(char *p)
{
return cmdline_parse_core(p, &required_kernelcore);
}
/*
* movablecore=size sets the amount of memory for use for allocations that
* can be reclaimed or migrated.
*/
static int __init cmdline_parse_movablecore(char *p)
{
return cmdline_parse_core(p, &required_movablecore);
}
early_param("kernelcore", cmdline_parse_kernelcore);
early_param("movablecore", cmdline_parse_movablecore);
另外函式find_zone_movable_pfns_for_nodes 用于計算進入可移動區域的記憶體數量,
對一個每個結點來說,zone_movable_pfn[node_id] 表示movable_zone記憶體域的起始地址,同required_kernelcore一樣, 這也是一個關鍵的變數,
參考:
[0] 深入Linux內核架構
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/283072.html
標籤:其他
上一篇:回應式微服務Spring Cloud與Spring WebFlux(二)之 鏈路跟蹤
下一篇:【博客414】Go gin框架
