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

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

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

3天內不再提示

glibc內存管理存在的共性問題及解決方法

Linux閱碼場 ? 來源:Linux閱碼場 ? 作者:劉冬云 ? 2021-06-18 14:50 ? 次閱讀

引言

對于嵌入式設備來說,用戶態內存管理是一項基礎功能,目前主流的用戶態內存管理庫有glibc、uclibc、tcmalloc、jemalloc等。

本文基于glibc2.17版本進行分析,圍繞glibc內存分配原理、內存站崗問題形成原因展開討論,并對glibc緩存大量內存(高達幾十個 G甚至上百 G)且不釋放的問題給出一種解決方案。

筆者遇到的問題是基于glibc進行內存管理的64 位Linux系統。具體現象如下:設備32G物理內存,在大規格打流情況下,某用戶進程占用的物理內存暴漲至20G左右。

在停止打流后,觀察到業務模塊已經釋放了絕大部分內存,但是進程占用的物理內存依然達到16G左右,此后內存狀況一直維持該狀態,導致系統內存緊張,若疊加上其他業務則出現了OOM的現象,已排除該進程內存泄露的可能性。

1

Glibc內存分配基本原理

Glibc使用了ptmalloc的內存管理方式,本文在描述時均使用glibc來稱呼。Glibc申請內存時是從分配區申請的,分為主分配區和非主分配區,分配區都有鎖,在分配內存前需要先獲取鎖,然后再去申請內存。

一般進程都是多線程的,當多個線程同時需要申請內存時,如果只有一個分配區,那么效率太低。

glibc為了支持多線程的內存申請釋放,會在多個線程同時需要申請內存時根據cpu核數分配一定數量的分配區,將分配區分配給線程。如果線程數量較多,則會出現多個線程爭用一個分配區的的情況,這里不展開。

內存申請基本原理:當用戶調用malloc申請內存時,glibc會查看是否已經緩存了內存,如果有緩存則會優先使用緩存內存,返回一塊符合用戶請求大小的內存塊。

如果沒有緩存或者緩存不足則會去向操作系統申請內存(可通過brk、mmap申請內存),然后切一塊內存給用戶。

內存釋放基本原理:當業務模塊使用完畢后調用free釋放內存時,glibc會檢查該內存塊虛擬地址上下內存塊的使用狀態(fast bin除外)。若其上一塊內存空閑,則與上一塊內存進行合并。若下一塊內存空閑,則與下一塊內存進行合并。如圖2所示。

若下一塊內存時top chunk(top chunk一直是空閑的),則看top chunk的大小是否超過一個閾值,如果超過一個閾值則將其釋放給OS。

2

Glibc內存站崗及其原因

內存站崗概念:

內存站崗指的是glibc從OS申請到內存后分配給業務模塊,業務模塊使用完畢后釋放了內存,但是glibc沒有將這些空閑內存釋放給OS,也就是緩存了很多空閑內存無法歸還給系統的現象。

內存站崗原因:

glibc設計時就確定其內存是用于短生命周期的,因此在設計上內存釋放給OS的時機是當top chunk的大小超過一個閾值時會釋放top chunk的一部分內存給OS。當top chunk不超過閾值就不會釋放內存給OS。

那么問題來了,若與top chunk相鄰的內存塊一直在使用中,那么top chunk就永遠也不會超過閾值,即便業務模塊釋放了大量內存,達到幾十個G 或者上百個G,glibc也是無法將內存還給OS的。

對于glibc來說,其有主分配和非主分配區的概念。主分配通過sbrk來增加分配區的內存大小,而非主分配區則是通過一個或多個mmap出來的內存塊用鏈表鏈接起來模擬主分配區的。為了更清晰的解釋內存站崗,下面舉個例子來說明主分配區的內存站崗。

如上有(a) (c) (e) (g)內存塊正在使用,故而導致了空閑內存(b) (d) (f)無法和top chunk連成一塊更大的空閑內存塊,glibc的閾值(64位系統默認是128K),盡管目前空閑內存有將近130M,也無法還給OS。

接下來看非主分配區的內存站崗,實際的非主分配區可能有很多個heap,這里假設只有4個heap。

在定位過程中,筆者與同事討論過多次如何解決站崗。在一次討論過程中由鄧竑杰提出降低heap的size(類似于tcmalloc的做法),雖然實測后發現完全沒有效果,但是為后續解決問題起到了啟示作用。

后面筆者在走讀代碼時發現這是glibc原生機制,同時筆者在查看內存布局時觀察到非主分配區大量heap均為free狀態。原有機制是先釋放heap3,如果heap3有內存在使用,盡管heap0、heap1、heap2的內存都釋放了,那也是無法釋放給系統。

glibc有多個分配區,每個分配區都幾百 M 空閑內存的話,則整個進程占用達到幾十個G也就不奇怪了。

3

Glibc內存站崗解決方法及patch

在內存釋放時,對于主分配區和非主分配其走的流程是不一樣的,我們64位系統的進程內存模型為經典模式,棧是從高地址向低地址生長的。

對于主分配區的內存站崗我還沒有遇到過,若主分配區內存站崗,一種方法是可以嘗試madvise將主分配區的pagesize對齊的空閑內存進行釋放,但是這樣效果可能不太明顯。

另外一種是通過創建線程,然后將主線程的業務移到新線程即可,這樣主分配區就不會造成站崗了,而將站崗轉移到了非主配區,而非主分配區則是我們接下來要進行優化的主戰場。

針對非主分配區進行兩處優化:a) heap0,heap1,heap2是空閑的,那么我們就可以將heap1,heap2釋放掉;b) heap默認是64M,降低每個heap的size(筆者測試時設置為512K)。

這里需要特別解釋一下為什么不釋放heap0和最后一個heap3,heap0的組成如圖7所示。圖左邊是第一個heap即heap0,圖右邊是最后一個heap即heap3。

從圖中可以清晰的看到如若釋放掉heap0那么會將struct malloc_state結構體釋放,會造成進程崩潰。右邊這個由于有在用的內存,也不能釋放掉。當然如果heap3的內存全部被釋放了,則由glibc原生代碼進行了處理,patch不再處理。

經過修改glibc源碼,優化其釋放機制,實際打流測試。

在打流到峰值后,進程使用了20G的內存,在停止打流后數秒內便恢復到了打流前的內存水平,進程所占用的內存基本還給系統了。至此,glibc內存站崗問題得到解決。

以上我們介紹了如何解決內存站崗的原理,紙上得來終覺淺,現在我們看patch源碼實現。

目前筆者已經將該優化的patch提交到開源社區審核,提交到社區的patch未對heap的size進行修改,這是因為想要謹慎一些,畢竟開源的代碼使用場景較多,如有需要可自行決定heap的size。

Patch基于glibc2.17代碼

1. Index: arena.c2. ===================================================================3. --- arena.c (revision 2)4. +++ arena.c (working copy)5. @@ -652,7 +652,7 @@6.7. static int8. internal_function9. -heap_trim(heap_info *heap, size_t pad)10. +heap_trim(heap_info *heap, heap_info* free_heap, size_t pad)11. {12. mstate ar_ptr = heap-》ar_ptr;13. unsigned long pagesz = GLRO(dl_pagesize);14. @@ -659,7 +659,29 @@15. mchunkptr top_chunk = top(ar_ptr), p, bck, fwd;16. heap_info *prev_heap;17. long new_size, top_size, extra, prev_size, misalign;18. + heap_info *last_heap;19.20. + /*Release heap if possible*/21. + last_heap = heap_for_ptr(top_chunk);22. + if ((NULL != free_heap-》prev) && (last_heap != free_heap)){23. + p = chunk_at_offset(free_heap, sizeof(*free_heap));24. + if (!inuse(p)){25. + if (chunksize(p)+sizeof(*free_heap)+MINSIZE==free_heap-》size){26. + while (last_heap){27. + if (last_heap-》prev == free_heap){28. + last_heap-》prev == free_heap-》prev;29. + break;30. + }31. + last_heap = last_heap-》prev;32. + }33. + ar_ptr-》system_mem -= free_heap-》size;34. + arena_mem -= free_heap-》size;35. + unlink(p, bck, fwd);36. + delete_heap(free_heap);37. + return 1;38. + }39. + }40. + }41. /* Can this heap go away completely? */42. while(top_chunk == chunk_at_offset(heap, sizeof(*heap))) {43. prev_heap = heap-》prev;44. Index: malloc.c45. ===================================================================46. --- malloc.c (revision 2)47. +++ malloc.c (working copy)48. @@ -915,7 +915,7 @@49. # if __WORDSIZE == 3250. # define DEFAULT_MMAP_THRESHOLD_MAX (512 * 1024)51. # else52. -# define DEFAULT_MMAP_THRESHOLD_MAX (4 * 1024 * 1024 * sizeof(long))53. +# define DEFAULT_MMAP_THRESHOLD_MAX (256 * 1024)54. # endif55. #endif56.57. @@ -3984,7 +3984,7 @@58. heap_info *heap = heap_for_ptr(top(av));59.60. assert(heap-》ar_ptr == av);61. - heap_trim(heap, mp_.top_pad);62. + heap_trim(heap, heap_for_ptr(p), mp_.top_pad);63. }64. }

4

結束語

不同的內存管理方式均有其優勢和缺陷,由于工作需要,筆者有幸研究過glibc、tcmalloc、uclibc內存管理,本文討論了glibc內存管理存在的一個共性問題,并給出可行的解決方案。

對于內存站崗問題,一般的做法是用戶自己緩存一些長時間不釋放的內存。另一種是干脆將glibc替換為tcmalloc。因為 tcmalloc 的 span比較小,所以站崗發生的概率極低,即便發生也就站崗一個span的大小。若由于某些原因不能用tcmalloc代替glibc的場景,如上的解決思路可以嘗試一下,該問題也困擾我們多時了,花費了較長時間和較多精力去定位。

在glibc2.28的版本中,glibc有了tcache的特性,對于業務進程使用大量小內存的場景則更加容易出現內存站崗問題。在撰寫本文時查看了glibc2.33版本,開源社區還未對該問題進行修改(或許是開源社區大神認為這不是glibc的問題,而是用戶不釋放內存)。

編輯:jq

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

    關注

    87

    文章

    11319

    瀏覽量

    209832
  • 代碼
    +關注

    關注

    30

    文章

    4801

    瀏覽量

    68735
  • Glibc
    +關注

    關注

    0

    文章

    9

    瀏覽量

    7515

原文標題:Linux glibc 內存站崗問題及解決方法

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

收藏 人收藏

    評論

    相關推薦

    gitee 常見問題及解決方法

    Gitee作為國內的代碼托管平臺,在使用過程中可能會遇到一些問題。以下是一些常見問題及其解決方法: 一、倉庫創建與代碼推送問題 倉庫已存在遠程配置 問題 :在嘗試為已有項目添加遠程倉庫配置時,可能會
    的頭像 發表于 01-06 10:06 ?89次閱讀

    交換機常見故障及解決方法 如何優化交換機的性能

    交換機常見故障及解決方法 交換機的常見故障主要包括物理層故障、端口協商及自環問題、VLAN問題、設備兼容性問題以及其他問題。以下是對這些故障及其解決方法的詳細闡述: 物理層故障 硬件故障 :如電路板
    的頭像 發表于 12-12 18:02 ?604次閱讀

    RAM內存不足的表現及解決方法

    RAM內存不足的表現及解決方法 一、RAM內存不足的表現 系統運行緩慢 當RAM內存不足時,計算機的響應速度會明顯下降,打開程序或文件需要更長的時間。 頻繁的頁面交換(Page Swa
    的頭像 發表于 11-11 09:53 ?1308次閱讀

    Mobaxterm 常見問題與解決方法

    強大,但用戶在使用過程中可能會遇到一些問題。以下是一些常見問題及其解決方法: 1. 連接問題 問題: 無法連接到遠程服務器。 解決方法: 確認服務器地址和端口號是否正確。 檢查網絡連接是否正常。 確認服務器是否允許SSH/Telnet等連接。 查看是否有防火墻或安全軟件阻
    的頭像 發表于 11-10 15:35 ?3324次閱讀

    高速PCB信號和電源完整性問題的建模方法研究

    高速PCB信號和電源完整性問題的建模方法研究
    發表于 09-21 14:13 ?0次下載

    CAN盒指示燈不亮的解決方法

    CAN盒指示燈不亮可能有多種原因,以下是一些常見的解決方法
    的頭像 發表于 09-20 14:53 ?695次閱讀

    內存管理的硬件結構

    常見的內存分配函數有malloc,mmap等,但大家有沒有想過,這些函數在內核中是怎么實現的?換句話說,Linux內核的內存管理是怎么實現的?
    的頭像 發表于 09-04 14:28 ?341次閱讀
    <b class='flag-5'>內存</b><b class='flag-5'>管理</b>的硬件結構

    pcb設計中遇到的常見問題及解決方法

    電氣或機械規范。 解決方法 : 確保所有設計元素(如焊盤、孔徑、走線寬度和間距)符合IPC標準。 使用自動化設計規則檢查(DRC)工具來識別和修正問題。 2. 材料選擇問題 問題 :選擇了不適合應用的材料。 解決方法 : 根據應用需求(如溫度
    的頭像 發表于 09-02 14:53 ?2379次閱讀

    接地網阻值偏大的原因及解決方法

     地網接地電阻測試儀是保障電氣設備安全運行的重要組成部分,但在實際使用中,我們可能會遇到接地網阻值偏大的情況。接下來,鴻蒙小小編介紹造成這種情況的原因,并提供一些解決方法。   1、接地體積不足
    發表于 06-17 09:19

    鴻蒙OpenHarmony:【常見編譯問題和解決方法

    常見編譯問題和解決方法
    的頭像 發表于 05-11 16:09 ?2300次閱讀

    UPS蓄電池運維管理解析,內阻抗監測數據

    石油化工行業大量使用UPS電源,對UPS蓄電池的運維管理仍然存在不少問題。本文對電池普遍存在的使用共性問題進行歸類總結,結合主動電池安全運維管理
    的頭像 發表于 05-11 09:07 ?707次閱讀
    UPS蓄電池運維<b class='flag-5'>管理</b>解析,內阻抗監測數據

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

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

    分析電源電感發熱解決方法

    電子發燒友網站提供《分析電源電感發熱解決方法.docx》資料免費下載
    發表于 03-29 14:39 ?3次下載

    EMI電磁干擾:原理、影響及解決方法詳解?

    EMI電磁干擾:原理、影響及解決方法詳解?|深圳比創達電子
    的頭像 發表于 03-21 10:02 ?898次閱讀
    EMI電磁干擾:原理、影響及<b class='flag-5'>解決方法</b>詳解?

    glibc malloc內存分配器的實現原理

    內存(Heap Memory)是一個很有意思的領域。你可能和我一樣,也困惑于下述問題很久了。
    的頭像 發表于 01-17 10:03 ?856次閱讀
    <b class='flag-5'>glibc</b> malloc<b class='flag-5'>內存</b>分配器的實現原理
    主站蜘蛛池模板: 久久精品国产欧美| 嗯好舒服嗯好大好猛好爽| 欧美牲交A欧美牲交| 自拍偷拍2| 久青草国产97香蕉在线视频| 亚洲永久在线观看| 后入式狂顶免费视频| 亚洲一日韩欧美中文字幕在线| 国精产品一区二区三区有限公司| 学生妹被爆插到高潮无遮挡| 国产一区亚洲| 亚洲国产精品久久精品成人网站| 国产午夜久久影院| 亚洲国产cao| 精品久久伊人| 一本道亚洲区免费观看| 久久偷拍人| 97人妻精品全国免费视频| 欧美精品专区第1页| 成人永久免费视频| 婷婷综合亚洲爱久久| 国产深夜福利视频在线| 一本久道视频无线视频| 麻豆Av国产在线播放| seyeye高清视频在线| 少妇久久久久久被弄高潮| 国产又色又爽又刺激在线播放| 一本之道高清在线观看一区| 麻美ゆま夫の目の前で犯| 扒开黑女人p大荫蒂老女人 | 九色PORNY真实丨国产大胸| 中国明星16xxxxhd| 日本高清片免费观看| 国产线精品视频在线观看| 长篇高h肉爽文丝袜| 琪琪电影午夜理论片77网| 国产精品禁18久久久夂久| 一亲二脱三插| 欧美特级特黄AAAAA片| 国产人妻人伦精品久久久| 在线观看中文字幕码2021不用下载 |