亚洲一级簧片_性 毛片_国产乱子视频_久久影城_强伦女教师视频_成人精品久久

電腦系統內存泄露

發布時間: 2023-04-16 17:43 閱讀: 文章來源:轉載

現象

某線上運行的C++服務,在一臺機器上訪問失敗率很高,監控顯示如下圖:

登錄問題機器,發現該服務占用的內存高達30G,這是不正常的,疑似內存泄露。為了減少服務運行損失,先把該機器摘掉,再進行問題分析。

分析

從現象上來看,服務的失敗率,主要原因是內存泄露,導致內存占用高,從而影響到服務的正常運行。內存泄露大體可以分為兩種:

1、申請了內存,沒有釋放,代碼實現上的bug。

2、全局(或常駐內存)變量,因為某種原因申請了大量的內存,由于其生命周期未結束,暫時還沒有釋放。這可能是一種設計上的bug。

于是,查看了線上其他機器,并沒有發現內存占用過高的情況,同時,也沒有發現內存持續增長。從這個方面來看,更傾向于第二種情況,或者是機器自身問題。查看了問題機器上,該服務的運行日志及系統日志,并沒有發現明顯的問題。

因此,需要從服務進程去定位問題,分析步驟:

  • dump服務

為了不影響線上業務,需要快速恢復服務。于是,先使用gcore命令將運行的進程dump下來,保存現場,命令如下:

# gcore 24564(進程pid)

執行命令后,會在當前目錄下生成一個該進程的core dump文件了。接著,重啟服務后,觀察了一段時間,并沒有發現內存持續增長。

  • 查看內存映射

使用gdb調試剛才dump下來的core dump文件,查看進程中內存分配情況,如下:

(gdb) maintenance info sections………… 0x7f8c18000000->0x7f8c1c000000 at 0x3af828854: load398 ALLOC LOAD HAS_CONTENTS0x7f8c1c000000->0x7f8c1ffff000 at 0x3b3828854: load399 ALLOC LOAD HAS_CONTENTS0x7f8c1ffff000->0x7f8c20000000 at 0x3b7827854: load400 ALLOC LOAD READONLY HAS_CONTENTS0x7f8c20000000->0x7f8c23fe0000 at 0x3b7828854: load401 ALLOC LOAD HAS_CONTENTS0x7f8c23fe0000->0x7f8c24000000 at 0x3bb808854: load402 ALLOC LOAD READONLY HAS_CONTENTS0x7f8c28000000->0x7f8c2bffa000 at 0x3bb828854: load403 ALLOC LOAD HAS_CONTENTS0x7f8c2bffa000->0x7f8c2c000000 at 0x3bf822854: load404 ALLOC LOAD READONLY HAS_CONTENTS0x7f8c30000000->0x7f8c34000000 at 0x3bf828854: load405 ALLOC LOAD HAS_CONTENTS0x7f8c38000000->0x7f8c3c000000 at 0x3c3828854: load406 ALLOC LOAD HAS_CONTENTS0x7f8c40000000->0x7f8c43ffe000 at 0x3c7828854: load407 ALLOC LOAD HAS_CONTENTS0x7f8c43ffe000->0x7f8c44000000 at 0x3cb826854: load408 ALLOC LOAD READONLY HAS_CONTENTS………………

可以看到分配了大量的內存,猜測這些內存塊就是泄露的。為了定位到內存泄露的代碼,嘗試查看了這些幾個內存塊中的內容,看看是否能看到一些字符串或者有規律的內容,但是,并沒有發現有價值的線索。

  • 排查全局變量

在gdb中,使用info variables命令,可以將進程中的全局變量,打印出來。但是由于引用了很多的第三方庫等,可能輸出內容會比較多。因此,可以考慮通過腳本進行過濾,重點排查該服務相關的變量。這里并不是說,第三方庫不會有問題,但是,目前嫌疑最大的仍然是我們寫的代碼。針對篩選出來的全局變量,進行排查。重點檢查的內容有,數組、vector、map等各種容器大小。

在排查中,發現其中一個全局變量中queue對象的_M_map_size = 10485758,這是不正常的。

(gdb) p Singleton::instance_->query_queue_$2 = {queue_ = {c = {, std::allocator<char> >, std::allocator, std::allocator<char> > > >> = {_M_impl = {, std::allocator<char> > >> = {<__gnu_cxx::new_allocator, std::allocator<char> > >> = {}, },members of std::_Deque_base, std::allocator<char> >, std::allocator, std::allocator<char> > > >::_Deque_impl:_M_map = 0x7f8ac2fff010,_M_map_size = 10485758,_M_start = {_M_cur = 0x7f8c08040f68,_M_first = 0x7f8c08040d70,_M_last = 0x7f8c08040f70,_M_node = 0x7f8ac5c17e80},_M_finish = {_M_cur = 0x7f903532af30,_M_first = 0x7f903532ade0,_M_last = 0x7f903532afe0,_M_node = 0x7f8ac7822960}}}, }},}

可以看到,這是一個使用std::queue實現的隊列,queue的內存結構由一個中控器(map)、多個緩沖區和兩個迭代器(start和finish)組成。其中,中控器是一個連續的內存塊,每個元素指向一個緩沖區。start和finish迭代器分別指向隊列中頭和尾。緩沖區中,存放隊列中元素地址。如下:

根據調試信息,可以計算出:

map中node個數為:(0x7f8ac7822960-0x7f8ac5c17e80)/8=3675484個。

每個node對應一個緩沖區,緩沖區的大小為0x7f8c08040f70 - 0x7f8c08040d70 = 512字節。

由于地址占8字節,因此一個緩沖區中有:512/8=64個元素。

當前隊列中,元素總數為:3675484*64=235230976

通過查看內存中字符串占的內存,可以發現,緩存的字符串占用內存平均在100字符左右,計算這部分內存為:(235230976*100)/(1024*1024*1024.0)=21.9G。

與泄露的內存大小基本符合?;究梢哉J為,是由于隊列中緩存元素過多,導致了服務的內存泄露。

  • 閱讀源碼

通過閱讀源碼,可以看到該變量的所在模塊的功能是:實現一個帶過期時間的緩存。具體實現邏輯是:每次請求從該緩存模塊中取得一個key的緩存值,若該key已經在緩存中,且未過期,則直接返回對應的緩存值。若沒有在緩存中(或已經過期),該將該key寫入到一個隊列中,由另一個更新線程去后臺查詢更新該key對應的緩存。

造成隊列中數據大量堆積的可能原因是,某一時刻,更新線程查詢后臺時,出現了延時,引發堆積。由于訪問量很大,且過期時間設定得較短,再加上,隊列中重復key也并不會去重。因此,只要發生抖動,就會發生大量堆積,最終導致內存激增,服務異常。

為了驗證問題,重新查看運行日志,確實能找到查詢后臺服務失敗的相關日志,只是報錯日志量不大,在最開始查看日志時,并未引起注意。至此,基本可以確認該問題。

總結

對于線上問題處理來說,一般的原則是,先快速恢復服務,后定位問題。比如,因為新功能上線,導致服務異常,首先做的是代碼回滾。本文中通過gcore將進程的內存dump下來,能較好地保存現場,同時,重啟進程,恢復服務。因為已經保存了進程當時的內存狀態,可以給分析問題提供較大地便利和更多地依據。

內存泄露的排查方法和工具有很多,如何在不重啟服務、不重新編譯、最小性能影響等方式下,快速定位到進程內存泄露點,仍有一定的挑戰。

???展開全文
相關文章
主站蜘蛛池模板: 精品视频免费看 | 经典三级在线播放 | 99久久婷婷国产综合精品免费 | 亚洲欧美日韩久久精品 | 国产精品成av人在线视午夜片 | 国内精品久久久久久久97牛牛 | 精品久久中文字幕 | 久久久成人网 | 97在线视频免费 | 男人都懂得网站 | 免费在线成人 | 免费在线小视频 | 6—12呦国产精品 | 国产精品久久久一区二区三区 | 尤物精品 | 国产日韩欧美一区二区 | 亚洲图片一区二区 | 久久不色| 精品自拍视频 | 欧美一级片在线看 | 欧洲精品一区 | 日韩精品一二三区 | 日韩精品一区二区久久 | 国产影视| www.射| 成人午夜免费电影 | 国产精品久久久久永久免费观看 | 久久91久久 | 99精品国产一区二区青青牛奶 | 日本一区二区视频 | 国产免费看 | 国产疯狂做受xxxx高潮 | 精品国产一区二区三区性色av | 日韩在线观看视频免费 | 精品一区二区三区三区 | 日韩福利在线 | 日本特黄a级高清免费大片 韩国精品久久久 | 日韩精品中文字幕一区二区三区 | 91成人在线播放 | 国产精品久久久久婷婷二区次 | 美女航空一级毛片在线播放 |