女人自慰AV免费观看内涵网,日韩国产剧情在线观看网址,神马电影网特片网,最新一级电影欧美,在线观看亚洲欧美日韩,黄色视频在线播放免费观看,ABO涨奶期羡澄,第一导航fulione,美女主播操b

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

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

3天內(nèi)不再提示

glibc導致的堆外內(nèi)存泄露的排查過程

OSC開源社區(qū) ? 來源:阿里云開發(fā)者 ? 2023-09-01 09:43 ? 次閱讀

阿里妹導讀

本文記錄一次glibc導致的堆外內(nèi)存泄露的排查過程。

問題現(xiàn)象

團隊核心應用每次發(fā)布完之后,內(nèi)存會逐步占用,不重啟或者重新部署就會導致整體內(nèi)存占用率超過90%。

dcb20a6c-47ef-11ee-97a6-92fbcf53809c.png

發(fā)布2天后的內(nèi)存占用趨勢

探索原因一

堆內(nèi)找到原因

出現(xiàn)這種問題,第一想到的就是集群中隨意找一臺機器,信手dump一下內(nèi)存,看看是否有堆內(nèi)存使用率過高的情況。 dcd53b36-47ef-11ee-97a6-92fbcf53809c.png 內(nèi)存泄露 dd002152-47ef-11ee-97a6-92fbcf53809c.png 泄露對象占比 發(fā)現(xiàn) 占比18.8%

問題解決

是common-division這個包引入的

dd21defa-47ef-11ee-97a6-92fbcf53809c.png 暫時性修復方案

當前加載俄羅斯(RU)國際地址庫,改為一個小國家地址庫 以色列(IL)

當前業(yè)務使用場景在補發(fā)場景下會使用,添加打點日志,確保是否還有業(yè)務在使用該服務,沒人在用的話,直接下掉(后發(fā)現(xiàn),確還有業(yè)務在用呢 )。

完美解決問題,要的就是速度??!發(fā)布 ~~上線??!順道記錄下同一臺機器的前后對比。 dd482650-47ef-11ee-97a6-92fbcf53809c.png

發(fā)布后短時間內(nèi)有個內(nèi)存增長實屬正常,后續(xù)在做觀察。

發(fā)布第二天,順手又dump一下同一臺機器的內(nèi)存 ddd00f98-47ef-11ee-97a6-92fbcf53809c.png 由原來的18.8%4.07%的占比,降低了14%,牛皮??! 傻了眼,內(nèi)存又飆升到86%~~ 該死的迷之自信?。?/strong> ddf63baa-47ef-11ee-97a6-92fbcf53809c.png 發(fā)布后內(nèi)存使用率

探索原因二

沒辦法匯報了~~~ 但是問題還是要去看看為什么會占用這么大的內(nèi)存空間的~

查看進程內(nèi)存使用

de43352c-47ef-11ee-97a6-92fbcf53809c.png

java 進程內(nèi)存使用率 84.9%,RES 6.8G。

查看堆內(nèi)使用情況

當期機器配置為 4Core 8G,堆最大5G,堆使用為不足3G左右。

deb48d9e-47ef-11ee-97a6-92fbcf53809c.png 使用arthas的dashboard/memory 命令查看當前內(nèi)存使用情況: def96b12-47ef-11ee-97a6-92fbcf53809c.png 當前堆內(nèi)+非堆內(nèi)存加起來,遠不足當前RES的使用量。那么是什么地方在占用內(nèi)存??

開始初步懷疑是『堆外內(nèi)存泄露』

開啟NMT查看內(nèi)存使用

筆者是預發(fā)環(huán)境,正式環(huán)境開啟需謹慎,本功能有5%-10%的性能損失!??!

-XX:NativeMemoryTracking=detail


jcmd pid VM.native_memory
df3a66a8-47ef-11ee-97a6-92fbcf53809c.png 如圖有很多內(nèi)存是Unknown(因為是預發(fā)開啟,相對占比仍是很高)。

概念 NMT displays “committed” memory, not "resident" (which you get through the ps command). In other words, a memory page can be committed without considering as aresident(until it directly accessed).

rssAnalyzer 內(nèi)存分析

筆者沒有使用,因為本功能與NMT作用類似,暫時沒有截圖了~ rssAnalyzer(內(nèi)部工具),可以通過oss在預發(fā)/線上下載。

通過NMT查看內(nèi)存使用,基本確認是堆外內(nèi)存泄露。 剩下的分析過程就是確認是否堆外泄露,哪里在泄露。

堆外內(nèi)存分析

查了一堆文檔基本思路就是

pmap 查看內(nèi)存地址/大小分配情況

確認當前JVM使用的內(nèi)存管理庫是哪種

分析是什么地方在用堆外內(nèi)存。

內(nèi)存地址/大小分配情況

pmap 查看

pmap -x 2531 | sort -k 3 -n -r
df8c4630-47ef-11ee-97a6-92fbcf53809c.png

劇透: 32位系統(tǒng)中的話,多為1M 64位系統(tǒng)中,多為64M。

strace 追蹤

由于系統(tǒng)對內(nèi)存的申請/釋放是很頻繁的過程,使用strace的時候,無法阻塞到自己想要查看的條目,推薦使用pmap。

strace -f -e"brk,mmap,munmap" -p 2853 原因: 對 heap 的操作,操 作系統(tǒng)提供了 brk()函數(shù),C 運行時庫提供了 sbrk()函數(shù);對 mmap 映射區(qū)域的操作,操作系 統(tǒng)提供了 mmap()和 munmap()函數(shù)。sbrk(),brk() 或者 mmap() 都可以用來向我們的進程添 加額外的虛擬內(nèi)存。Glibc 同樣是使用這些函數(shù)向操作系統(tǒng)申請?zhí)摂M內(nèi)存。

e0196218-47ef-11ee-97a6-92fbcf53809c.png

查看JVM使用內(nèi)存分配器類型

發(fā)現(xiàn)很大量為[anon](匿名地址)的64M內(nèi)存空間被申請。通過附錄參考的一些文檔發(fā)現(xiàn)很多都提到64M的內(nèi)存空間問題(glibc內(nèi)存分配器導致的),抱著試試看的態(tài)度,準備看看是否為glibc。

cd /opt/taobao/java/bin
ldd java
e02705d0-47ef-11ee-97a6-92fbcf53809c.png

glibc為什么會有泄露

e05ba592-47ef-11ee-97a6-92fbcf53809c.png 我們當前使用的glibc的版本為2.17。說到這里可能簡單需要介紹一下glibc的發(fā)展史。

V1.0時代』Doug Lea Malloc 在Linux實現(xiàn),但是在多線程中,存在多線程競爭同一個分配分配區(qū)(arena)的阻塞問題。

V2.0時代』Wolfram Gloger 在 Doug Lea 的基礎上改進使得 Glibc 的 malloc 可以支持多線程——ptmalloc。

glibc內(nèi)存釋放機制(可能出現(xiàn)泄露時機)

調用free()時空閑內(nèi)存塊可能放入 pool 中,不一定歸還給操作系統(tǒng)。

.收縮堆的條件是當前 free 的塊大小加上前后能合并 chunk 的大小大于 64KB、,并且 堆頂?shù)拇笮∵_到閾值,才有可能收縮堆,把堆最頂端的空閑內(nèi)存返回給操作系統(tǒng)。

『V2.0』為了支持多線程,多個線程可以從同一個分配區(qū)(arena)中分配內(nèi)存,ptmalloc 假設線程 A 釋放掉一塊內(nèi)存后,線程 B 會申請類似大小的內(nèi)存,但是 A 釋放的內(nèi) 存跟 B 需要的內(nèi)存不一定完全相等,可能有一個小的誤差,就需要不停地對內(nèi)存塊 作切割和合并。

e069d978-47ef-11ee-97a6-92fbcf53809c.png

為什么是64M

回到前面說的問題,為什么會創(chuàng)建這么多的64M的內(nèi)存區(qū)域。這個跟glibc的內(nèi)存分配器有關下的,間作介紹。 V2.0版本的glibc內(nèi)存分配器,將分配區(qū)域分配主分配區(qū)(main arena)和非主分配區(qū)(non main arena)(在v1.0時代,只有一個主分配區(qū),每次進行分配的時候,需要對主分配區(qū)進行加鎖,2.0支持了多線程,將分配區(qū)通過環(huán)形鏈表的方式進行管理),每一個分配區(qū)利用互斥鎖使線程對于該分配區(qū)的訪問互斥。

主分配區(qū):可以通過sbrk/mmap進行分配。

非主分配區(qū),只可以通過mmap進行分配。

其中,mmap每次申請內(nèi)存的大小為HEAP_MAX_SIZE(32 位系統(tǒng)上默認為 1MB,64 位系統(tǒng)默 認為 64MB)。

哪里在泄露

既然知道了存在堆外內(nèi)存泄露,就要查一下到低是什么地方的內(nèi)存泄露。參考歷史資料,可以使用jemalloc工具進行排查。

配置dump內(nèi)存工具(jemalloc)

由于系統(tǒng)裝載的是glibc,所以可以自己在不升級jdk的情況下編譯一個jemalloc。

github下載比較慢,上傳到oss,再做下載。


sudo yum install -y git gcc make graphviz 
    wget -P /home/admin/general-aftersales https://xxxx.oss-cn-zhangjiakou.aliyuncs.com/jemalloc-5.3.0.tar.bz2 &&  
    mkdir   /home/admin/general-aftersales/jemalloc && 
    cd  /home/admin/general-aftersales/ && 
    tar -jxcf  jemalloc-5.3.0.tar.bz2 && 
    cd  /home/admin/xxxxx/jemalloc-5.3.0/ && 
    ./configure  --enable-prof && 
    make && 
    sudo make install


export LD_PRELOAD=/usr/local/lib/libjemalloc.so.2  MALLOC_CONF="prof:true,lg_prof_interval:30,lg_prof_sample:17,prof_prefix:/home/admin/general-aftersales/prof_prefix

核心配置

make之后,需要啟用prof,否則會出現(xiàn)『: Invalid conf pair: prof:true』類似的關鍵字

配置環(huán)境變量

LD_PRELOAD 掛載本次編譯的庫

MALLOC_CONF 配置dump內(nèi)存的時機。

"lg_prof_sample:N",平均每分配出 2^N 個字節(jié) 采一次樣。當 N = 0 時,意味著每次分配都采樣。

"lg_prof_interval:N",分配活動中,每流轉 1 ? 2^N 個字節(jié),將采樣統(tǒng)計數(shù)據(jù)轉儲到文件。

重啟應用

./appctl restart

監(jiān)控內(nèi)存dump文件

如果上述配置成功,會在自己配置的prof_prefix 目錄中生成相應的dump文件。 然后將文件轉換為svg格式


jeprof --svg /opt/taobao/java/bin/java prof_prefix.36090.9.i9.heap > 36090.svg
然后就可以在瀏覽器中瀏覽了 e0838364-47ef-11ee-97a6-92fbcf53809c.png

與參閱文檔中結果一致,有通過Java java.util.zip.Inflater調用JNI申請內(nèi)存,進而導致了內(nèi)存泄露。

既然找到了哪里存在內(nèi)存泄露,找到使用的地方就很簡單了。

發(fā)現(xiàn)元兇

通過arthas 的stack命令查看某個方法的調用棧。

statck java.util.zip.Inflater 

java.util.zip.InflaterInputStream

e120ec44-47ef-11ee-97a6-92fbcf53809c.pnge12c03e0-47ef-11ee-97a6-92fbcf53809c.png 如上源碼可以看出,如果使用InflaterInputStream(InputStream?in)?來構造對象usesDefaultInflater=true, 否則全部為false; 在流關閉的時候。 e1df5bac-47ef-11ee-97a6-92fbcf53809c.pnge263af92-47ef-11ee-97a6-92fbcf53809c.png

end()是native方法。

只有在『usesDefaultInflater=true』的時候,才會調用free()將內(nèi)存歸嘗試歸還OS,依據(jù)上面的內(nèi)存釋放機制,可能不會歸還,進而導致內(nèi)存泄露。

comp.taobao.pandora.loader.jar.ZipInflaterInputStream

二方包掃描

e298f0c6-47ef-11ee-97a6-92fbcf53809c.png ZipInflaterInputStream 的流關閉使用的是父類java.util.zip.InflaterInputStream,構造器使用public?InflaterInputStream(InputStream?in,?Inflater?inf,?int?size) 這樣如上『usesDefaultInflater=false』,在關閉流的時候,不會調用end()方法,導致內(nèi)存泄露。 com.taobao.pandora.loader.jar.ZipInflaterInputStream 源自pandora ,咨詢了相關負責人之后,發(fā)現(xiàn)2年前就已經(jīng)修復此內(nèi)存泄露問題了。

最低版本要求 sar包里的 pandora 版本,要大于等于 2.1.17

問題解決

升級ajdk版本

需要咨詢一下jdk團隊的同學,需要使用jemalloc作為內(nèi)存分配器的版本。

升級pandora版本

如上所說,版本高于2.1.17即可。

我們是團隊是統(tǒng)一做的基礎鏡像,找相關的同學做了dockerfile from的升級。

發(fā)布部署&觀察

e2b4e18c-47ef-11ee-97a6-92fbcf53809c.pnge2dcdd0e-47ef-11ee-97a6-92fbcf53809c.pnge3003aba-47ef-11ee-97a6-92fbcf53809c.png 這此真的舒服了~ ?

總結

探究了glibc的工作原理之后,發(fā)現(xiàn)相比jemalloc的內(nèi)存使用上確實存在高碎片率的問題,但是本次問題的根本還是在應用層面沒有正確的關閉流加劇的堆外內(nèi)存的泄露。

總結的過程,也是學習的過程,上述分析過程歡迎評論探討。

審核編輯:湯梓紅

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

    關注

    8

    文章

    3108

    瀏覽量

    74985
  • Glibc
    +關注

    關注

    0

    文章

    9

    瀏覽量

    7621
  • 內(nèi)存泄露

    關注

    0

    文章

    6

    瀏覽量

    2053

原文標題:實戰(zhàn)總結|記一次glibc導致的堆外內(nèi)存泄露

文章出處:【微信號:OSC開源社區(qū),微信公眾號:OSC開源社區(qū)】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦
    熱點推薦

    波特率漂移導致通信異常的故障排查過程

    示波器的協(xié)議解碼功能大家都不生疏,你是否有過波形看起來正常,協(xié)議參數(shù)、解碼設置都正確,卻無法正常解碼的經(jīng)歷呢?本文以UART協(xié)議為例,分享由于波特率漂移導致通信異常的故障排查過程。
    的頭像 發(fā)表于 01-08 13:51 ?6686次閱讀
    波特率漂移<b class='flag-5'>導致</b>通信異常的故障<b class='flag-5'>排查過程</b>

    分享一種內(nèi)存泄漏定位排查技巧

    常見的泄漏方式在嵌入式開發(fā)中,經(jīng)常會使用malloc,free分配釋放內(nèi)存,稍不小心就可能導致內(nèi)存一點點地泄露,直至
    發(fā)表于 12-17 08:13

    如何有效地排查內(nèi)存泄露的疑難問題

    不太輕易去改動里面的代碼,這無疑也增大了排查難度。在這樣的背景下,要完成從“復雜度”如此高的代碼里面找出可能出現(xiàn)【內(nèi)存泄露】的幾行問題代碼,需要有點手段才行。3 解決思路根據(jù)多年對【
    發(fā)表于 09-01 14:47

    單片機C語言幾種內(nèi)存泄露總結

    程序的設計的錯誤導致這部分內(nèi)存沒有被釋放,那么此后這塊內(nèi)存將不會被使用,就會產(chǎn)生Heap Leak. 這是最常見的內(nèi)存泄露。
    發(fā)表于 11-14 10:09 ?2669次閱讀
    單片機C語言幾種<b class='flag-5'>內(nèi)存</b><b class='flag-5'>泄露</b>總結

    Java開發(fā)者必須了解的內(nèi)存技術

    先來看一個 Demo:在 Demo 中分配內(nèi)存用的是 allocateDirect 方法,但其內(nèi)部調用的是 DirectByteBuffer,換言之,DirectByteBuffer 才是實際操作
    發(fā)表于 07-01 10:19 ?3871次閱讀
    Java開發(fā)者必須了解的<b class='flag-5'>堆</b><b class='flag-5'>外</b><b class='flag-5'>內(nèi)存</b>技術

    DC-DC電源故障排查過程和總結,珍貴的經(jīng)驗!資料下載

    電子發(fā)燒友網(wǎng)為你提供DC-DC電源故障排查過程和總結,珍貴的經(jīng)驗!資料下載的電子資料下載,更有其他相關的電路圖、源代碼、課件教程、中文資料、英文資料、參考設計、用戶指南、解決方案等資料,希望可以幫助到廣大的電子工程師們。
    發(fā)表于 04-25 08:54 ?75次下載
    DC-DC電源故障<b class='flag-5'>排查過程</b>和總結,珍貴的經(jīng)驗!資料下載

    glibc內(nèi)存管理存在的共性問題及解決方法

    引言 對于嵌入式設備來說,用戶態(tài)內(nèi)存管理是一項基礎功能,目前主流的用戶態(tài)內(nèi)存管理庫有glibc、uclibc、tcmalloc、jemalloc等。 本文基于glibc2.17版本進行
    的頭像 發(fā)表于 06-18 14:50 ?3619次閱讀

    什么是內(nèi)存?內(nèi)存是如何分配的?

    在一般的編譯系統(tǒng)中,內(nèi)存的分配方向和棧內(nèi)存是相反的。當棧內(nèi)存從高地址向低地址增長的時候,內(nèi)存
    的頭像 發(fā)表于 07-05 17:58 ?1w次閱讀

    Glibc內(nèi)存管理之Ptmalloc2源代碼分析

    Glibc內(nèi)存管理之Ptmalloc2源代碼分析
    發(fā)表于 07-29 09:20 ?24次下載

    Java內(nèi)部類持有外部類導致內(nèi)存泄露的原因以及其解決方案

    簡介 為什么要持有外部類 實例:持有外部類 實例:不持有外部類 實例:內(nèi)存泄露 不會內(nèi)存泄露的方案 簡介 「說明」 本文介紹 Java 內(nèi)部類持有外部類
    的頭像 發(fā)表于 10-08 16:32 ?1157次閱讀

    mtrace分析內(nèi)存泄露

    一、mtrace分析內(nèi)存泄露 mtrace(memory trace),是 GNU Glibc 自帶的內(nèi)存問題檢測工具,它可以用來協(xié)助定位內(nèi)存
    的頭像 發(fā)表于 11-13 10:55 ?1594次閱讀
    mtrace分析<b class='flag-5'>內(nèi)存</b><b class='flag-5'>泄露</b>

    內(nèi)存是如何泄露

    作為 C++ 程序員,內(nèi)存泄露始終是懸在頭上的一顆炸彈。在過去幾年的 C++ 開發(fā)過程中,由于我們采用了一些技術,我們的程序發(fā)生內(nèi)存泄露的情
    的頭像 發(fā)表于 11-13 14:13 ?555次閱讀
    <b class='flag-5'>內(nèi)存</b>是如何<b class='flag-5'>泄露</b>的

    java內(nèi)存溢出排查方法

    Java內(nèi)存溢出(Memory overflow)是指Java虛擬機(JVM)中的內(nèi)存無法滿足對象分配的需求,導致程序拋出OutOfMemoryError異常。
    的頭像 發(fā)表于 11-23 14:46 ?3790次閱讀

    Java怎么排查oom異常

    據(jù)量的應用中。要排查OOM異常,需要經(jīng)過以下幾個步驟: 理解OOM異常的原因:OOM異常通常有以下幾個原因:內(nèi)存泄露、內(nèi)存溢出、內(nèi)存不足以容
    的頭像 發(fā)表于 12-05 13:47 ?1523次閱讀

    Java應用OOM問題的排查過程

    導讀 本文記錄最近一例Java應用OOM問題的排查過程,希望可以給遇到類似問題的同學提供參考。 前言:此文記錄最近一例Java應用OOM問題的排查過程,希望可以給遇到類似問題的同學提供參考。在本地
    的頭像 發(fā)表于 02-12 11:15 ?553次閱讀
    Java應用OOM問題的<b class='flag-5'>排查過程</b>