色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

邢孟棒:2個壓箱底的方法和工具搞定內存泄漏

Linux閱碼場 ? 來源:Linux閱碼場 ? 2023-01-17 09:40 ? 次閱讀
導讀|遭受內存泄露往往是令開發者頭疼的問題,傳統分析工具 gdb、Valgrind在解決內存泄露問題上效率較低。本文特別邀請到了騰訊后臺開發工程師邢孟棒以 TDSQL實際生產中mysql-proxy內存泄露問題作為分析對象,分享其基于動態追蹤技術的通用內存泄露(增長)分析方法。其中將詳細介紹內存分配器行為分析、缺頁異常事件分析,涵蓋應用程序內存分配的常見過程。閱讀完本文后,開發者僅需關注少數可能導致內存泄露的代碼路徑,就能有效提升定位內存泄露(增長)問題的效率。 背景某個 TDSQL 私有化環境中, 中間件 mysql-proxy 進行大量請求轉發時,內存占用量持續增長導致 OOM 現象,最終影響了用戶業務的正常使用 。本人分析該問題的過程中發現一個較為普遍的業務痛點:傳統分析工具(gdb、Valgrind 等)效率相對較低,在私有化場景中尤其突出。針對這一痛點,我將提供相對通用的內存泄露(增長)分析方法,協助各位開發者更高效地定位發生泄露的代碼路徑,以期最大化減少人力投入成本并降低對用戶業務體驗的影響。

基礎概念

在展開講述內存泄露(增長)分析方法之前,我們先了解一些相關的基礎概念。 內存泄露包括內核內存泄露應用程序內存泄露兩大類。內核內存泄露可以通過 kmemleak 進行檢測,本文主要關注應用程序的內存泄露。應用程序的內存泄露又可以細分為:堆內存(Heap)泄露、內存映射區(Memory Mappings)泄露。我們平時提及的內存泄露主要是指物理內存的泄露(持續分配、映射實際的物理內存,且一直未釋放),危害較大,需要立即修復。 另外,虛擬內存的泄露(持續分配虛擬內存,但未分配、映射實際的物理內存)容易被忽視,雖然危害相對較小,但也需額外關注(進程的內存映射區總數量有上限,默認 1w)。 通常,應用程序內存分配涉及的步驟大致如下圖所示:第一,應用程序通過內存分配器(例如 libc)提供的 malloc 及其變體函數申請內存,free 函數釋放相應內存。第二,內存分配器(例如 libc)內部通過系統調用 brk 擴展堆內存(小塊內存分配)。第三,內存分配器(例如 libc)內部通過系統調用 mmap 分配內存映射區域(大塊內存分配,默認不小于 128 KB)第四,二或三已申請的虛擬內存在首次寫入時觸發缺頁異常,OS 分配實際物理頁面,并將虛擬內存與其相關聯,記錄至頁表。 其中,步驟一至三均為虛擬內存,步驟四分配實際物理內存并創建相應頁表。

ff3b4b9a-95fa-11ed-bfe3-dac502259ad0.jpg

傳統分析工具 gdb、Valgrind

在定位 mysql-proxy 內存泄露(增長)問題的過程中,開發人員嘗試使用了 Valgrind Memcheck、gdb 進行協助分析。最終前者實際效果不太理想;我通過后者分析出泄露原因,但整個過程耗費了較多時間。 gdb 是常用的程序調試工具,好處不用贅述。但對于內存泄露或增長問題,gdb 缺點也較為明顯,大致如下:干擾程序正常運行,不適合生產環境;直接定位比較困難,且要求對源碼有一定了解 Valgrind Memcheck 是一款知名度較高的內存泄露分析工具,非常強大,開發調試過程中能夠快速發現場景的內存泄露問題。不過開發者在使用之前,建議對以下情況有所了解:第一,需要重啟程序,且作為 Valgrind 子進程運行。不適合分析正在發生內存增長的進程第二,替代默認的 malloc/free 等分配函數,目標進程運行速度減慢 20~30 倍。第三,不能很好的支持 tcmalloc、jemalloc 內存分配器。(mysql-proxy 采用了 jemalloc 內存分配器)

基于動態追蹤的通用分析方法

對于正在運行、內存持續增長的應用來說,gdb、Valgrind Memcheck 工具其實都挺難發揮價值。相比而言,動態追蹤技術提供了一種通用且易用的方式。內存分配器相關函數調用、系統調用、缺頁異常等,都可以看作一個個事件。通過對這些事件的追蹤、統計等,我們可以分析有關內存使用情況的具體代碼路徑,在不深入源碼細節的前提下快速縮小泄露發生的范圍。 本文涉及兩種基于動態追蹤的通用分析方法:內存分配器行為分析缺頁異常事件分析,涵蓋應用程序內存分配的常見過程。

1)內存分配器行為分析

內存分配器(glibc、jemalloc 等)行為分析整體思路如下:首先,站在應用視角,重點關注應用程序內存分配的代碼路徑。其次,動態追蹤內存分配相關函數,統計未釋放內存分配的調用棧與總字節數量,形成分析工具 memstacks。
  • 開發新工具 memstacks

該工具支持生成兩種類型的火焰圖:一種是僅追蹤 malloc 及其變體函數,不做 free 抵消,結果可用于生成全量內存分配火焰圖。另一種是追蹤 malloc 及其變體函數、free 函數,計算出追蹤期間未釋放的內存分配,結果可用于生成未釋放內存分配火焰圖。 其實現原理大致如下:借鑒現有 BCC 工具 memleak、mallocstacks,支持生成折疊棧,可生成全量內存分配火焰圖、未釋放內存分配火焰圖。借助 uprobes 動態追蹤 malloc(以及變體 cmalloc、realloc)、free。ff524c64-95fa-11ed-bfe3-dac502259ad0.jpg 如上圖所示,現有 BCC 工具 memleak、mallocstacks 各有優劣。新工具 memstacks 結合兩者優點,允許有選擇性的生成全量內存分配火焰圖或者未釋放內存分配火焰圖需要的折疊棧格式
  • 全量內存分配火焰圖

執行以下命令,追蹤 mysql-proxy 進程所有 malloc 及其變體調用 60s,并生成全量內存分配火焰圖。

	
# 步驟 1. 追蹤 60s,生成全量內存分配折疊棧
# 其中,參數 -a 表示追蹤所有的 malloc 及其變體,但不追蹤 free 進行相互抵消。參數 -f 表示生成折疊棧,用于步驟 2 生成火焰圖。
./memstacks -p $(pgrep -nx mysql-proxy) -af 60 > all_mallocs.stacks


# 步驟 2. 執行下述命令生成全量內存分配火焰圖,輸出至文件 all_mallocs.svg。
./flamegraph.pl --color=mem --title="All malloc() bytes Flame Graph" --countname="bytes" < all_mallocs.stacks > all_mallocs.svg
火焰圖如下所示,可以協助開發者理解 mysql-proxy 調用 malloc 及其變體的關鍵代碼路徑。ff5ca1dc-95fa-11ed-bfe3-dac502259ad0.jpg
  • 未釋放內存分配火焰圖

執行以下命令,追蹤 mysql-proxy 進程未釋放 malloc 及其變體調用 60s,并生成內存分配火焰圖。

	
# 步驟 1. 追蹤 60s,生成未釋放內存分配折疊棧
# 其中,參數 -f 表示生成折疊棧,用于步驟 2 生成火焰圖。
memstacks -p $(pgrep -nx mysql-proxy) -f 60 > unfreed_mallocs.stacks


# 步驟 2. 執行下述命令生成未釋放內存分配火焰圖,輸出到文件 unfreed_mallocs.svg。
./flamegraph.pl --color=mem --title="Unfreed malloc() bytes Flame Graph" --countname="bytes" < unfreed_mallocs.stacks > unfreed_mallocs.svg
火焰圖如下所示,其中:未釋放內存共計 27.75 MB(追蹤期間,通過 pidstat 觀察到 mysql-proxy 進程 RSS 增量接近 27 MB,與未釋放內存統計量 27.75 MB 基本一致)。 已分配但未釋放的代碼路徑主要有兩處。其中,據研發反饋,tdsql::set_str 正是導致 mysql-proxy 內存泄露發生的地方。而另一處并非真正的泄露。該工具有一定的副作用,由于追蹤的最后階段有一些剛分配的內存還未來得及釋放,需要進一步閱讀源碼甄別。另外,建議多運行幾次對比下結果,排除那些經常變化的分配路徑。ff66296e-95fa-11ed-bfe3-dac502259ad0.jpg 對已分配但未釋放的代碼路徑展開,結果如下:ff6d906e-95fa-11ed-bfe3-dac502259ad0.jpg

ff769812-95fa-11ed-bfe3-dac502259ad0.jpg ?相比全量內存分配火焰圖,數據量減少近 60 倍,需要重點關注的代碼路徑的減少也比較明顯。因此,推薦優先使用未釋放內存分配火焰圖進行分析。

2)缺頁異常事件分析

相比內存分配器行為分析,缺頁異常事件分析提供了另一種視角,整體思路如下:首先,站在內核視角,關注的是首次寫入觸發缺頁異常的代碼路徑,而不是觸發內存分配的代碼路徑。前者是進程 RSS增長的原因,后者僅分配了虛擬內存,尚未映射物理內存。其次,追蹤缺頁異常事件,統計未釋放物理內存的調用棧與總頁面數量,形成分析工具 pgfaultstacks。
  • 現有分析工具

傳統工具 perf,基于軟件事件 page-faults

	
perfrecord-p$(pgrep-nxmysql-proxy)-epage-faults-c1-g--sleep60
BCC 工具 stackcount基于靜態追蹤點 exceptions:page_fault_user。

	
stackcount -p $(pgrep -nx mysql-proxy) -U tpage_fault_user
現有分析工具雖然方便,但是以增量的方式去統計,不考慮追蹤過程中被釋放的物理內存,最終統計的結果通常會偏大,對內存泄露(增長)的分析會造成干擾。
  • 缺頁異常火焰圖(現有版)

執行以下命令,追蹤 mysql-proxy 進程所有缺頁事件 60s,并生成缺頁異常火焰圖。
perf record -p $(pgrep -nx mysql-proxy) -e page-faults -c 1 -g -- sleep 60 > pgfault.stacks


./flamegraph.pl --color=mem --title="Page Fault Flame Graph" --countname="pages" < pgfault.stacks > pgfault.svg
火焰圖具體如下,共計 420,342 次缺頁事件,但不是每一次缺頁事件都分配一個新的物理頁面(大多數情況下未分配),mysql-proxy RSS 實際增長量僅 60 多MB 。ff7f4d72-95fa-11ed-bfe3-dac502259ad0.jpg
  • 開發新工具 pgfaultstacks

該工具的實現原理大致如下:第一,改進現有缺頁事件統計方式(過濾物理頁面已存在的缺頁事件,并在追蹤完成后讀取目標進程的內存映射列表,通過計算將已釋放的物理頁面排除在外),僅關注真正泄露的物理內存。 第二,借助 tracepoint 或 kprobe 動態追蹤 page faults 事件,一般情況下性能開銷可忽略不計。
  • 缺頁異常火焰圖

執行以下命令,追蹤 mysql-proxy 進程滿足過濾條件的缺頁事件 60s,并生成缺頁火焰圖。

	
# 步驟 1. 追蹤 60s,生成缺頁異常折疊棧。其中,參數 -f 表示生成折疊棧,用于步驟 2 生成火焰圖。
pgfaultstacks -p $(pgrep -nx mysql-proxy) -f 60 > pgfault.stacks


# 步驟 2. 生成缺頁火焰圖,輸出到文件 pgfault.svg。
./flamegraph.pl --color=mem --title="Page Fault Flame Graph" --countname="pages" < pgfault.stacks > pgfault.svg
缺頁火焰圖如下,其中:共計增加 17801 個物理頁面(與 mysql-proxy 進程 RSS 增量基本一致)。重點關注函數 g_string_append_printf。(注:非內存泄露發生的環境,僅用來演示缺頁異常火焰圖)ff8b5e8c-95fa-11ed-bfe3-dac502259ad0.jpg 相比現有版,該版本的數據量減少 20 多倍,需要重點關注的代碼路徑減少也比較明顯。

總結

本文以 TDSQL 實際生產中 mysql-proxy 內存泄露問題作為分析對象,探索基于動態追蹤技術的通用內存泄露(增長)分析方法:內存分配器行為分析缺頁異常事件分析,并針對現有分析工具進行改進,形成相應的分析工具 memstacks、pgfaultstacks,歡迎各位開發者嘗試去開發。工具使用者僅需關注少數可能導致內存泄露的代碼路徑,有效提升定位內存泄露(增長)問題的效率。如果你正在遭受內存泄露(增加)的困擾,不妨嘗試下本文提及的分析方法和工具,希望有所幫助。 審核編輯 :李倩

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 內存
    +關注

    關注

    8

    文章

    3020

    瀏覽量

    74008
  • 代碼
    +關注

    關注

    30

    文章

    4780

    瀏覽量

    68529
  • 應用程序
    +關注

    關注

    37

    文章

    3267

    瀏覽量

    57682

原文標題:邢孟棒:2個壓箱底的方法和工具搞定內存泄漏

文章出處:【微信號:LinuxDev,微信公眾號:Linux閱碼場】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    免費泄漏率計算工具,讓氣密性檢測變得簡單高效

    在工業生產中,泄漏率是衡量產品氣密性能的重要指標,它如同「健康體檢報告」,精準反映設備的密封狀態,及時預警潛在的安全隱患與質量風險。一微小的泄漏,可能導致能源浪費、安全事故甚至環境污染。因此,掌握
    的頭像 發表于 12-18 11:54 ?75次閱讀
    免費<b class='flag-5'>泄漏</b>率計算<b class='flag-5'>工具</b>,讓氣密性檢測變得簡單高效

    虛擬內存溢出該怎么處理 虛擬內存在服務器中的應用

    、虛擬內存溢出的原因 內存泄漏 :程序中未正確釋放的內存會導致內存泄漏,隨著時間的推移,這些
    的頭像 發表于 12-04 09:49 ?136次閱讀

    性分析方法及其應用

    性(Robustness)是指系統或方法對于外部干擾、誤差或變化的穩定性和適應能力。以下是對魯性分析方法的詳細介紹,以及其在不同領域的應用實例。 一、魯
    的頭像 發表于 11-11 10:21 ?895次閱讀

    開關電源輻射老是超?教你一方法搞定

    開關電源輻射老是超?教你一方法搞定它【樣機介紹】我本次調試的樣機主控IC為思睿達主推的成都啟臣微的CR52168BSG,此IC內封了一顆700V的三極管,主要優勢為價格低廉、外圍簡單,同時支持
    的頭像 發表于 10-16 08:02 ?584次閱讀
    開關電源輻射老是超?教你一<b class='flag-5'>個</b>好<b class='flag-5'>方法</b><b class='flag-5'>搞定</b>它

    堆棧和內存的基本知識

    本文主要聊聊關于堆棧的內容。包括堆棧和內存的基本知識。常見和堆棧相關的 bug,如棧溢出,內存泄漏,堆內存分配失敗等。后面介紹軟件中堆棧統計的重要性,以及如何使用
    的頭像 發表于 08-29 14:10 ?450次閱讀
    堆棧和<b class='flag-5'>內存</b>的基本知識

    不到10塊錢,用Ai-M61-32S如何自制一開機

    本作品由安信可社區用戶 Yhue 制作 當你出門在外時,領導一電話打來需要資料,這時候需要同事去幫忙開機查找,其實只要一根可以遠程開機電腦的“小棒子”,輕松搞定這一切。究竟是什么棒子這般厲害呢
    的頭像 發表于 08-27 16:17 ?300次閱讀
    不到10塊錢,用Ai-M61-32S如何自制一<b class='flag-5'>個</b>開機<b class='flag-5'>棒</b>?

    如何檢測內存泄漏

    檢測內存泄漏是軟件開發過程中一項至關重要的任務,它有助于識別和解決那些導致程序占用過多內存資源,從而影響程序性能甚至導致程序崩潰的問題。以下將詳細闡述幾種常見的內存
    的頭像 發表于 07-30 11:50 ?1813次閱讀

    包裝泄漏性檢測方法—真空衰減法

    MLT系列微泄漏無損密封測試儀依據《ASTM F2338-2013 包裝泄漏的標準檢測方法-真空衰減法》標準研發。適用于預充式 注射器、水針及粉針瓶(玻璃/塑料)、灌裝壓蓋瓶、奶粉罐、其他硬質
    的頭像 發表于 07-23 16:51 ?803次閱讀
    包裝<b class='flag-5'>泄漏</b>性檢測<b class='flag-5'>方法</b>—真空衰減法

    NONOS 1.5.3/1.5.4 SSL內存泄漏的原因?

    我已經通過隨附的代碼驗證了當發生 SSL 握手錯誤時,會生成內存泄漏 此外,espconn_reconnect_callback不稱為信令ESPCONN_HANDSHAKE - TCP SSL 握手
    發表于 07-18 07:24

    使用system_show_malloc()檢查內存泄漏遇到異常怎么解決?

    我想使用system_show_malloc()檢查內存泄漏,但是當我調用該函數時,我得到了致命的異常: 致命異常 28 (LoadProhibitedCause): epc1
    發表于 07-10 06:32

    如何正確連接和使用泰克電流探

    在電子工程領域,準確測量電流是診斷電路問題和驗證設計性能的關鍵步驟。泰克(Tektronix)電流探是一種精密工具,它允許工程師在不中斷電路的情況下測量電流。本文將指導您如何正確連接和使用泰克電流
    的頭像 發表于 07-04 11:44 ?668次閱讀
    如何正確連接和使用泰克電流探<b class='flag-5'>棒</b>

    華為專利公布:內存管理方法及相關設備

    該專利主要講述如何通過特定方法優化內存管理效率,包括確定N具有相同虛擬地址但權限各異的進程(N必須為大于或等于2的整數),并據此建立特定映射關系表以及權限表,每一進程均對應一
    的頭像 發表于 04-16 09:51 ?413次閱讀
    華為專利公布:<b class='flag-5'>內存</b>管理<b class='flag-5'>方法</b>及相關設備

    C語言內存泄漏問題原理

    內存泄漏問題只有在使用堆內存的時候才會出現,棧內存不存在內存泄漏問題,因為棧
    發表于 03-19 11:38 ?521次閱讀
    C語言<b class='flag-5'>內存</b><b class='flag-5'>泄漏</b>問題原理

    【鴻蒙】webview內存泄漏問題的分析報告

    1 關鍵字 webview;內存泄漏 2 問題描述 問題現象:在 3.1release 版本和 3.2bete1 版本中,在 RK3568 上使用 etsWeb 和其他瀏覽器時,webview 所占
    的頭像 發表于 03-02 15:12 ?2140次閱讀

    內存不夠用的處理方法

    內存不夠用的處理方法 內存不夠用是許多計算機用戶普遍面臨的問題。當我們的計算機內存不足時,會導致系統運行緩慢,應用程序無法正常運行,甚至直接導致計算機崩潰。然而,幸運的是,我們有很多
    的頭像 發表于 12-28 11:15 ?1052次閱讀
    主站蜘蛛池模板: 色翁荡熄月月| 久久精品久久久| 亚洲中文久久精品AV无码| 最近中文字幕完整版免费高清| 老少配xxxxx欧美| bl肉yin荡受np各种play| 日韩欧美视频一区二区| 国产免费播放一区二区三区| 亚洲精品乱码久久久久久v| 久久热在线视频精品1| 9久高清在线不卡免费无吗视频| 久久精品综合电影| 99国产精品久久| 人与人特黄一级| 国产免费变态视频网址网站 | 久久国产露脸老熟女熟69| 2019久久视频这里有精品15| 九九在线精品视频| 亚洲这里只有精品| 牛牛精品专区在线| metart中国撒尿人体欣赏| 王晶三级作品| 久久精品热播在线看| blacked黑人战小美女| 我的奶头被客人吸的又肿又红| 精品国产乱码久久久久久人妻| 亚洲精品一区三区三区在线观看| 绝逼会被锁| 99re5.久久热在线视频| 色欲AV无码乱码精品国产| 果冻传媒完整免费网站在线观看| 91精品国产色综合久久不| 暖暖直播免费观看韩国| yellow片在线观看免费观看动漫 | 正在播放国产精品| 秋霞久久久久久一区二区| 第四色男人天堂| 水蜜桃亚洲一二三四在线| 久久精品男人影院| 动漫成人片| 伊人热|