<strike id="ca4is"><em id="ca4is"></em></strike>
  • <sup id="ca4is"></sup>
    • <s id="ca4is"><em id="ca4is"></em></s>
      <option id="ca4is"><cite id="ca4is"></cite></option>
    • 二維碼
      企資網(wǎng)

      掃一掃關(guān)注

      當(dāng)前位置: 首頁 » 企業(yè)資訊 » 經(jīng)驗(yàn) » 正文

      如何跟蹤誰分配的每個頁面?

      放大字體  縮小字體 發(fā)布日期:2023-02-07 05:15:13    瀏覽次數(shù):85
      導(dǎo)讀

      問題背景Linux中常用得內(nèi)存分配API主要包括基于slab/slub得kmalloc等APIvmalloc相關(guān)APIalloc_pages等直接基于buddy得API我們可以在/proc/meminfo中輕易得到關(guān)于通過slab/slub API 或者vmalloc分配到得內(nèi)存。然而除非

      問題背景

      Linux中常用得內(nèi)存分配API主要包括

        基于slab/slub得kmalloc等API
        vmalloc相關(guān)API
        alloc_pages等直接基于buddy得API

        我們可以在/proc/meminfo中輕易得到關(guān)于通過slab/slub API 或者vmalloc分配到得內(nèi)存。然而除非內(nèi)核模塊主動進(jìn)行統(tǒng)計,內(nèi)核并沒有直接提供一個類似meminfo得方案來統(tǒng)計通過alloc_pages相關(guān)API申請得內(nèi)存。所以有時候當(dāng)kernel發(fā)生OOM得時候,我們發(fā)現(xiàn)有大量得內(nèi)存是unaccount得。

        為了統(tǒng)計這些直接從buddy申請走得內(nèi)存,內(nèi)核提供了page owner功能。

        概述

        page owner是用來追蹤誰分配得每一個頁面。它可以用來調(diào)試內(nèi)存泄漏或找到內(nèi)存占用者。當(dāng)分配發(fā)生時,有關(guān)分配得信息,如調(diào)用堆棧和頁面得順序被存儲到每個頁面得特定存儲中。當(dāng)我們需要了解所有頁面得狀態(tài)時,我們可以獲得并分析這些信息。

        盡管我們已經(jīng)有了追蹤頁面分配/釋放得tracepoint,但用它來分析誰分配得每個頁面是相當(dāng)復(fù)雜得。我們需要擴(kuò)大跟蹤緩沖區(qū),以防止在用戶空間程序啟動前出現(xiàn)重疊。而且,啟動得程序會不斷地將跟蹤緩沖區(qū)轉(zhuǎn)出,供以后分析,這將會改變系統(tǒng)得行為,會產(chǎn)生更多得可能性,而不是僅僅保留在內(nèi)存中,所以不利于調(diào)試。頁面所有者也可以用于各種目得。例如,可以通過每個頁面得gfp標(biāo)志信息獲得精確得碎片 統(tǒng)計。如果啟用了page owner,它就已經(jīng)實(shí)現(xiàn)并激活了。我們非常歡迎其他用途。

        page owner在默認(rèn)情況下是禁用得。所以,如果你想使用它,你需要在你得啟動cmdline 中加入”page_owner=on”。如果內(nèi)核是用page owner構(gòu)建得(使能宏CONFIG_PAGE_OWNER),并且由于沒有啟用啟動選項(xiàng)而在運(yùn)行時禁用page owner(即沒有在boot cmdline中添加 page_owner=on),那么運(yùn)行時得開銷是很小得。如果在運(yùn)行時禁用,它不需要內(nèi)存來存儲所有者信息,所以沒有運(yùn)行時內(nèi)存開銷。而且,page owner在頁面分配器得熱路徑中只插入了兩個不可能得分支,如果不啟用,那么分配就會像沒有page owner得內(nèi)核一樣進(jìn)行。這兩個不可能得分支應(yīng)該不會影響到分配得性能,特別是在靜態(tài)鍵跳轉(zhuǎn)標(biāo)簽修補(bǔ)功能可用得情況下。以下是由于這個功能而導(dǎo)致得內(nèi)核代碼大小得變化。

        沒有page owner:

        text data bss dec hex filename
        48392 2333 644 51369 c8a9 mm/page_alloc.o

        有page owner:

        text data bss dec hex filename
        48800 2445 644 51889 cab1 mm/page_alloc.o
        6662 108 29 6799 1a8f mm/page_owner.o
        1025 8 8 1041 411 mm/page_ext.o

        雖然總共增加了8KB得代碼,但page_alloc.o增加了520字節(jié),其中不到一半是在hotpath中。構(gòu)建帶有page owner得內(nèi)核,并在需要時打開它,將是調(diào)試內(nèi)核內(nèi)存問題得可靠些選擇。

        有一個問題是由實(shí)現(xiàn)細(xì)節(jié)引起得。頁所有者將信息存儲到struct page擴(kuò)展得內(nèi)存中。這個內(nèi)存得初始化時間比稀疏內(nèi)存系統(tǒng)中得頁面分配器啟動得時間要晚一些,所以,在初始化之前,許多頁面可以被分配,但它們沒有所有者信息。為了解決這個問題,這些早期分配得 頁面在初始化階段被調(diào)查并標(biāo)記為分配。雖然這并不意味著它們有正確得所有者信息,但至少,我們可以更準(zhǔn)確地判斷該頁是否被分配。在2GB內(nèi)存得x86-64虛擬機(jī)上,有13343 個早期分配得頁面被捕捉和標(biāo)記,盡管它們大部分是由結(jié)構(gòu)頁擴(kuò)展功能分配得。總之,在這之后,沒有任何頁面處于未追蹤狀態(tài)。

        使用方法
          構(gòu)建用戶空間得幫助

          cd tools/vm

          make page_owner_sort

            啟用page owner: 添加 “page_owner=on” 到 boot cmdline.
            做你想調(diào)試得工作
            分析來自頁面所有者得信息

            cat /sys/kernel/debug/page_owner > page_owner_full.txt

            ./page_owner_sort page_owner_full.txt sorted_page_owner.txt

            page_owner_full.txt 得一般輸出情況如下:

            Page allocated via order XXX, ...
            PFN XXX ...
            // Detailed stack

            Page allocated via order XXX, ...
            PFN XXX ...
            // Detailed stack

            page_owner_sort 工具忽略了 PFN 行,將剩余得行放在buf中,使用regexp提 取頁序值,計算buf得次數(shù)和頁數(shù),最后根據(jù)參數(shù)進(jìn)行排序。

            在 sorted_page_owner.txt 中可以看到關(guān)于誰分配了每個頁面得結(jié)果。一般輸出:

            XXX times, XXX pages:
            Page allocated via order XXX, ...
            // Detailed stack

            默認(rèn)情況下,page_owner_sort 是根據(jù)buf得時間來排序得。如果你想按buf得頁數(shù)排序,請使用-m參數(shù)。詳細(xì)得參數(shù)是:

            基本函數(shù):

            Sort:

            -a
            按內(nèi)存分配時間排序
            -m
            按總內(nèi)存排序
            -p
            按pid排序
            -P
            按tgid排序
            -r
            按內(nèi)存釋放時間排序
            -s
            按堆棧跟蹤排序
            -t
            按時間排序(默認(rèn))

            其它函數(shù):

            Cull:
            -c
            通過比較堆棧跟蹤而不是總塊來進(jìn)行剔除

            Filter:
            -f
            過濾掉內(nèi)存已被釋放得塊得信息

      end


      人人極客社區(qū)


      ,回復(fù)【peter】海量Linux資料贈送

      文章推薦

      ?【專輯】
      ?【專輯】
       
      (文/小編)
      免責(zé)聲明
      本文僅代表作發(fā)布者:個人觀點(diǎn),本站未對其內(nèi)容進(jìn)行核實(shí),請讀者僅做參考,如若文中涉及有違公德、觸犯法律的內(nèi)容,一經(jīng)發(fā)現(xiàn),立即刪除,需自行承擔(dān)相應(yīng)責(zé)任。涉及到版權(quán)或其他問題,請及時聯(lián)系我們刪除處理郵件:weilaitui@qq.com。