linux 內存回收mglru算法代碼注釋2

mglru與原lru算法的兼容

舊的lru算法有active與inactive兩代lru,可參考linux 內存回收代碼注釋(未實現多代lru版本)-CSDN博客

新的算法在引入4代lru的同時,還引入了tier的概念。

新舊算法的切換的實現在lru_gen_change_state,當開啟mglru時,調用fill_evictable,將active list 與 inactive list 的folio遷移到 mglru上(mglru的組織方式是:lruvec[gen][type][zone]),如果是關閉mglru,則調用drain_evictable,將mglru的folio遷移回active/inactive list兩代的情況。

當開啟mglru時,原有shrink_node與shrink_lruvec的路徑會短路,主要體現在兩個地方,對于全局的回收直接調用lru_gen_shrink_node,對于某個memory group 的回收會間接調用lru_gen_shrink_lruvec:

shrink_nodeif (lru_gen_enabled() && root_reclaim(sc)) {lru_gen_shrink_node(pgdat, sc);return;}shrink_lruvecif (lru_gen_enabled() && !root_reclaim(sc)) {lru_gen_shrink_lruvec(lruvec, sc);return;}

真正做頁的回收的邏輯還是在shrink_folio_list。?

mglru與原lru算法的差別

與舊的lru算法區別,主要有三個方面:1、修改了一次掃描要掃的數量計算邏輯。2、修改了代與代之間轉換的邏輯。3、添加了refault頁的延遲回收機制

mglru的組織

每個numa node 有一個 pgdat 結構,上面綁定了為每個memory group準備了兩代bin list,分別為young bin list和old bin list,第個bin list 上有8個bin,新加入的memory group會隨機找一個 bin list 加入(lru_gen_online_memcg)。回收總是在old代上做,找一個bin list,從頭掃描到尾。memory group 會隨著它分配的內存大小和是否做了回收,在old與young的bin list 頭尾上游走。(lru_gen_rotate_memcg),具體而言:

1、memory group 的內存超過?soft limit 時,將它移至同代的開頭,下次可能回收它(lru_gen_soft_reclaim,MEMCG_LRU_HEAD)

2、新加入的memory group會放在新代的結尾處,第一次掃描發現頁數少于2^priority或是第一次掃描發現頁數在low水位線以下時,會放在新代的結尾處(MEMCG_LRU_TAIL)

3、當第一次掃描發現內存在min水位以下,或第二次掃描發現上次掃描是小于2^priority的,或是每次掃描完足夠頁數時會把最后一個掃描的memory group 移至新代(MEMCG_LRU_YOUNG)。

4、在移除一個memory group時,需要回收全部內存,會把它放在old代(lru_gen_offline_memcg,MEMCG_LRU_OLD)

bin list 中每一項是memory group的lruvec指針。

lruvec內部分成了4代,每代有兩個type:文件or匿名,每個type又維護了每個zone上的頁框,如下:

// 找一個 group 對應在某個 node 上的lru
lruvec = &memcg->nodeinfo[pgdat->node_id]->lruvec.lrugen;
// 遍歷一個 node 上某個 binlist 的 lru 
lrugen = pgdat->memcg_lru.fifo[gen][bin];
// lru 內的頁框
lrugen->folios[gen][type][zone]

掃描數量

原有的swappiness表示回收匿名頁與文件頁的加權,取值1~200,值越小越支持從匿名頁回收。新算法計算掃描數量的方法變了,只根據swappiness有無賦值來決定要不要計算掃描匿名頁的數量,文件頁一定會掃描回收。計算的方式也比較粗暴:total >>?sc->priority;具體計算邏輯在get_nr_to_scan->should_run_aging。

代際轉換

如果在should_run_aging計算時發現最新一代的頁框數已經是總頁框數的一半,或第三代的頁框數小于總頁框數的四分之一,就觸發一次代際迭換,嘗試發現young 頁,把它們提升至最新代。代際迭換的代碼在try_to_inc_max_seq。

try_to_inc_max_seq():// 硬件不支持自動標記access flagif (!should_walk_mmu()) {iterate_mm_list_nowalk(lruvec, max_seq);return;}// 嘗試掃描 hot pmd 中的 young 頁。	do {is_last = iterate_mm_list(lruvec, walk, &mm);if (mm)walk_mm(lruvec, mm, walk);} while (mm);// 這一代掃描結束,更新代際if (is_last)inc_max_seq(lruvec, can_swap, force_scan);

如果硬件支持自動在頁表記錄訪問標記,則掃描一遍(掃描的實現在try_to_inc_max_seq->walk_mm->walk_pgd_range->walk_pud_range->walk_pmd_range->walk_pte_range),通過檢查bloom filter,找到標記為hot的pmd,訪問pmd中全部pte,將標記臟的pte對應頁框標記為臟,并更新至最新代。這里說的bloom filter標記了平均每個cacheline中young頁數大于1的pmd,只需要對這些pmd的全部pte中young 頁的掃描,并標記臟和更新代數,因為這個pmd范圍的young頁多,是個熱點區,意味著后面可能還會產生hot頁。如果硬件不支持自動設置訪問標記,就不能在這個地方掃了,而要等到建立rmap時,folio_referenced_one->lru_gen_look_around

bloom filter的設置有兩個途徑,一個是在上面說的掃描全部pte之后,計算young頁數/total頁數大于cacheline中能裝下的pte數(或者說是不是平均每個cacheline都有一個pte項對應了young頁,實現在suitable_to_scan);另一個是在shrink_folio_list時,會找一個頁框映射的次數(folio_referenced),會調一次lru_gen_look_around,嘗試看下這個pte對應的pmd中全部pte,同樣是在標記完臟頁、統計完young頁數時,計算young頁數/total頁數大于cacheline中能裝下的pte數,并把young 標記清掉。

這個過程大概代碼如下:


walk_pmd_range():
{
restart:for pmd_i in start_addr.. end_addr:// 檢查是不是hot pmdif (!test_bloom_filter(max_seq, pmd_i))continue;// 檢查hot pmd的所有pte中的臟頁,并統計young的頁數和清空young標記(young 指最近有訪問),計算它還是不是hot pmdis_still_hot = walk_pte_range(addr, pmd_end_addr);// 如果是hot的pmd,則在bloom filter 標記一下,下一輪(代)掃描時再檢查一次這個pmdif (is_still_hot)update_bloom_filter(max_seq + 1, pmd + i);}if (i < PTRS_PER_PMD && get_next_vma(PUD_MASK, PMD_SIZE, args, &start, &end))goto restart;
}walk_pte_range():new_gen = lru_gen_from_seq(walk->max_seq);
restart:for pte_i in start_addr.. end_addr:           {// 硬件標記pte臟的,但頁框沒有標記臟,且這是文件頁或未換出的匿名頁,則在頁框上標記下臟if (pte_dirty(ptent) && !folio_test_dirty(folio) &&!(folio_test_anon(folio) && folio_test_swapbacked(folio) &&!folio_test_swapcache(folio)))folio_mark_dirty(folio);// 將這一頁框更新到最新代old_gen = folio_update_gen(folio, new_gen);// 更新統計walk->nr_pages[old_gen][type][zone] 和 walk->nr_pages[new_gen][type][zone]if (old_gen >= 0 && old_gen != new_gen)update_batch_size(walk, folio, old_gen, new_gen);}if (i < PTRS_PER_PTE && get_next_vma(PMD_MASK, PAGE_SIZE, args, &start, &end))goto restart;// 計算young頁數/total頁數大于cacheline中能裝下的pte數(或者說是不是平均每個cacheline都有一個pte項對應了young頁)return suitable_to_scan(total, young);
}

Refault頁的延遲回收

refault指缺頁讀入后又換出又讀入。mglru引入tier概念,組織形式為lrugen->refaulted[hist][type][tier]。為file 和anon類型的頁,維護了4代統計直方圖(hist),每個直方圖中有4個范圍(tier),分別統計了本輪回收中訪問了1次,2次,4次,8次的頁數。

當觸發refault時,會統計累加本輪回收中,已經refault這么多次的頁數。(lru_gen_refault)

lru_gen_refault():// recent 指refault與上次回收在同一代內recent = lru_gen_test_recent(shadow, type, &lruvec, &token, &workingset);// 總共有4代histogram,根據當前代數算出它在那個histogram中hist = lru_hist_from_seq(READ_ONCE(lrugen->min_seq[type]));// 每代有4個tier,tier的index = log2(本輪掃描中這頁的 access 數),即分別為訪問1次,2次,4次,8次的tier。tier = lru_tier_from_refs(refs);// 統計累加本輪掃描過程中發生 2^tier 次 refault 的頁數。atomic_long_add(delta, &lrugen->refaulted[hist][type][tier]);

在決定是否回收頁時,evict_folios->isolate_folios,會平衡本輪發生refault 的頁數與回收+延時回收頁數的比值,計算一個控制值(refaulted/(evicted+protected)),可以理解為發生refault的頻繁程度。如果發生n次refault的頻繁程度達到了發生1次refault頻繁程度的2倍,則發生n次以上refault的頁都不再回收。

isolate_folios():// 計算refault次數超過多少后不再釋放tier_idx = get_tier_idx(lruvec, type);isolate_folios->scan_folios->sort_folio():// 本輪掃描中 refault 次數超過2^tier_idx 次的頁不再釋放,而是推到下一代if (tier > tier_idx) {// 將頁放在下一次lru尾(回收是從本代的頭開始的)gen = folio_inc_gen(lruvec, folio, false);list_move_tail(&folio->lru, &lrugen->folios[gen][type][zone]);// 累加本代中不釋放頁的頁數int hist = lru_hist_from_seq(lrugen->min_seq[type]);WRITE_ONCE(lrugen->protected[hist][type][tier - 1],lrugen->protected[hist][type][tier - 1] + delta);return true;}

在回收過程中,每完成一次分離出回收頁的計算后(isolate_folios),會將這一代的統計值更新為新值與歷史值的滑動平均值。

在一輪回收結束時,會調inc_max_seq將下一輪回收的代統計值清空,為最新代的統計留出位置。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/166312.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/166312.shtml
英文地址,請注明出處:http://en.pswp.cn/news/166312.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

ELK企業級日志分析平臺——elasticsearch

集群部署 文檔&#xff1a;https://www.elastic.co/guide/en/elasticsearch/reference/7.6/index.html 下載&#xff1a;https://elasticsearch.cn/download/ 主機 ip 角色 k8s1 192.168.92.11 cerebro elk1 192.168.92.31 elasticsearch elk2 192.168.92.32 elasti…

數據庫實驗五 數據庫設計

數據庫實驗五 數據庫設計 一、實驗目的二、實驗內容三、實驗內容四、驗證性實驗五、設計性實驗 一、實驗目的 1.了解E-R圖構成要素以及各要素圖元。 2.掌握概念模型E-R圖的繪制方法。 3.掌握概念模型向邏輯模型的轉換原則和步驟。 4.運用sql編程實現 二、實驗內容 1.選取一個…

線段樹---數據結構學習

線段樹的教程可以參照線段樹 這里推薦 https://oi-wiki.org/ 這個網站&#xff0c;數據結構講的非常透。 線段樹學了很多次忘了很多次&#xff0c;這次打算記錄一下以后方便回顧(leetcode這類題遇見的不算特別多)。 樣板例題 leltcode-307 #題目樣板 class NumArray {private …

醫院手術麻醉信息系統全套源碼,自主版權,支持二次開發

醫院手術麻醉信息系統全套商業源碼&#xff0c;自主版權&#xff0c;支持二次開發 手術麻醉信息系統是HIS產品的中的一個組成部分&#xff0c;主要應用于醫院的麻醉科&#xff0c;屬于電子病歷類產品。醫院麻醉監護的功能覆蓋整個手術與麻醉的全過程&#xff0c;包括手術申請與…

人工智能中的文本分類:技術突破與實戰指導

在本文中&#xff0c;我們全面探討了文本分類技術的發展歷程、基本原理、關鍵技術、深度學習的應用&#xff0c;以及從RNN到Transformer的技術演進。文章詳細介紹了各種模型的原理和實戰應用&#xff0c;旨在提供對文本分類技術深入理解的全面視角。 關注TechLead&#xff0c;分…

Hadoop發行版 Cloudera CDH 6.3.2及CM 安裝包下載(阿里云盤 不限速)

CDH&#xff08;全稱Cloudera’s Distribution, including Apache Hadoop&#xff09;是由Cloudera公司構建的Hadoop穩定發行版&#xff0c;不僅含有 Apache Hadoop&#xff0c;還整合了Hive、Spark等組件。 由于CDH已停止維護&#xff0c;且Cloudera不再為CDH提供免費的下載服…

git 使用過程錯誤集合

文章目錄 1、git-credential-manager-core was renamed to git-credential-manager2、credential-manager-core is not a git command. See git --help. 1、git-credential-manager-core was renamed to git-credential-manager 出現以下提示建議盡快更新您的 Git 配置以使用新…

回歸預測 | MATLAB實現SCN隨機配置網絡多輸入單輸出回歸預測

回歸預測 | MATLAB實現SCN隨機配置網絡多輸入單輸出回歸預測 目錄 回歸預測 | MATLAB實現SCN隨機配置網絡多輸入單輸出回歸預測效果一覽基本介紹程序設計參考資料 效果一覽 基本介紹 Matlab實現SCN隨機配置網絡多變量回歸預測 1.data為數據集&#xff0c;7個輸入特征&#xff0…

基于Python實現汽車銷售數據可視化+預測【500010086.1】

導入模塊 import numpy as np import pandas as pd from pylab import mpl import plotly.express as px import matplotlib.pyplot as plt import seaborn as sns設置全局字體 plt.rcParams[font.sans-serif][kaiti]獲取數據 total_sales_df pd.read_excel(r"./data/中…

獨孤思維:看了那么多課程,還在問怎么賺錢的都是廢物

你捫心自問&#xff1a; 為什么自己看了那么多賺錢項目&#xff0c;買了那么多課程&#xff0c;對標了那么多大咖&#xff0c;依舊賺不到錢&#xff1f; 是自己智商欠缺嗎&#xff0c;是自己能力不行嗎&#xff0c;是自己沒有時間嗎&#xff1f; 智商欠缺&#xff0c;沒有誰…

機器學習第13天:模型性能評估指標

??主頁 Nowl &#x1f525;專欄《機器學習實戰》 《機器學習》 &#x1f4d1;君子坐而論道&#xff0c;少年起而行之 文章目錄 交叉驗證 保留交叉驗證 k-折交叉驗證 留一交叉驗證 混淆矩陣 精度與召回率 介紹 精度 召回率 區別 使用代碼 偏差與方差 介紹 區…

zerotier 搭建 moon中轉服務器 及 自建planet

搭建moon 服務器 環境準備 # 安裝依賴 yum install wget gcc gcc-c git -y yum install json-devel -y# 下載及安裝 curl -s https://install.zerotier.com/ | sudo bash節點ID 配置 配置moon.json文件 cd /var/lib/zerotier-one/# 導出依賴 zerotier-idtool initmoon ide…

SpringBoot項目連接,有Kerberos認證的Kafka

在連接Kerberos認證kafka之前&#xff0c;需要了解Kerberos協議 二、什么是Kerberos協議 Kerberos是一種計算機網絡認證協議 &#xff0c;其設計目標是通過密鑰系統為網絡中通信的客戶機(Client)/服務器(Server)應用程序提供嚴格的身份驗證服務&#xff0c;確保通信雙方身份的真…

Spring Boot 升級3.x 指南

Spring Boot 升級3.x 指南 1. 升級思路 先創建一個parent項目&#xff0c;打包類型為pom&#xff0c;繼承自spring boot的parent項目 <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId&…

歷時三個月,我發布了一款外賣返錢小程序

近幾年&#xff0c;推廣外賣紅包爆火&#xff0c;各種推廣外賣紅包的公眾號層出不窮。于是&#xff0c;我就在想外賣紅包究竟是怎么一回事。就這樣&#xff0c;我帶著問題開始了關于外賣紅包的研究。 在研究的過程中&#xff0c;我開始了解商品聯盟、推廣分成、cps等一系列相關…

網絡攻擊當搭配什么產品比較好

網絡攻擊無處不在&#xff0c;當要時刻謹記 2014年&#xff0c;索尼影業受到黑客攻擊&#xff0c;導致公司內部文件和電子郵件泄露。 2015年&#xff0c;美國聯邦政府的辦公人員信息遭到盜竊&#xff0c;影響了超過2100萬人的個人信息。 2016年&#xff0c;Yahoo的3億用戶賬…

java 中集合之一【map】,map循環

在Java中&#xff0c;常用的集合框架有以下幾個&#xff1a; 1、List&#xff08;列表&#xff09;&#xff1a;List是有序的集合&#xff0c;允許包含重復元素。常用的實現類有ArrayList和LinkedList。ArrayList是基于動態數組實現的&#xff0c;支持快速隨機訪問&#xff1b;…

android之圖片選擇器--pictureselector

推薦一個安卓圖片/視頻/文件選擇器。簡單好用。 不多廢話。直接上代碼&#xff1a; 首先&#xff0c;添加依賴&#xff1a; //圖片選擇器api io.github.lucksiege:pictureselector:v3.11.1//圖片壓縮api io.github.lucksiege:compress:v3.11.1//圖片裁剪api io.github.lucksie…

Springboot3+vue3從0到1開發實戰項目(一)

一. 可以在本項目里面自由發揮拓展 二. 知識整合項目使用到的技術 后端開發 &#xff1a; Validation, Mybatis,Redis, Junit,SpringBoot3 &#xff0c;mysql&#xff0c;Swagger, JDK17 &#xff0c;項目部署 前端開發&#xff1a; Vue3&#xff0c;Vite&#xff0c;Router…

Java數組和集合

在Java中&#xff0c;數組和集合是兩個重要的概念&#xff0c;它們用于存儲和操作數據。本文將詳細介紹Java中的數組和集合&#xff0c;包括它們的定義、初始化、訪問和常見操作 一、數組&#xff08;Array&#xff09; 數組是一種用于存儲相同類型數據的容器&#xff0c;它可…