精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

一個耗時4小時的內存泄漏問題

開發 后端
首先確定內存泄漏問題出現的時間,發現在該時間點的上線有兩次代碼提交,其中一個就是我的。于是立刻排查這兩次代碼的改動,確定了另一個同事的代碼不可能會有內存問題后我知道肯定是自己的代碼出現了問題。

上周像往常一樣例行檢查線上機器性能,突然發現一個服務的內存使用率是這樣的:

很顯然該服務存在內存泄漏問題,趕緊排查問題。

問題排查

首先確定內存泄漏問題出現的時間,發現在該時間點的上線有兩次代碼提交,其中一個就是我的。于是立刻排查這兩次代碼的改動,確定了另一個同事的代碼不可能會有內存問題后(因為另一個同事的上線僅僅修改了配置)我知道肯定是自己的代碼出現了問題。

確定了問題所在后趕緊把自己的代碼回滾掉,接下來就可以放心debug了。

Debug

什么是內存泄漏?

簡單的講就是程序員申請的內存在使用完后沒有還給操作系統,由于筆者使用的是C++語言,因此內存泄漏一般是這樣的: 

  1. obj* o = new obj();  
  2. ...  
  3. // 使用完obj后沒有delete掉 

肯定有什么地方申請了內存后沒有調用delete釋放內存。

在這里介紹一下筆者的代碼改動,我的任務其實是重構一段代碼,把這段代碼并行化。也就是舊的邏輯是在一個線程中串行執行的,現在我要把這段邏輯放到兩個線程中并行執行,這是最讓人頭疼的任務之一,并行化改造是比較容易出bug的。

接下來梳理了一遍中所有內存的申請和釋放,這其中包括:

  •  使用new/delete分配釋放的內存
  •  使用內存池分配釋放的內存

仔細梳理一遍后沒有發現任何問題,該釋放的內存都已經釋放掉了,這時筆者已經開始懷疑人生了 :) ,很顯然還有一段沒有注意到的地方出現了問題,這是必然的,雖然知道問題必然出現在改動的這些代碼里但是我并不能確定出現的位置。

沒有辦法,到這里基本上已經要放棄自己人肉debug了,想利用一些內存檢測工具來幫助自己確定問題。

常見的內存泄漏檢測工具包括valgrind、gperftools等,valgrind的好處在于無需重新編譯代碼即可進行內存檢測,但是缺點是會使得程序運行非常緩慢,官方文檔給的說法是會比正常的程序運行慢20-30倍;gperftools則需要重新編譯可執行程序。這些工具需要下載安裝測試,其中還涉及到申請機器權限等問題,筆者覺得還是比較麻煩,況且這個問題也不是大海撈針一樣,問題肯定出在了并行化的這段代碼中。

到這里我決定再換一個思路來排查問題,既然代碼重構后開始并行執行,那么出現問題大概率是因為多線程問題,遇到多線程問題首先重點排查的就是線程間的共享數據。

多線程問題的關鍵——共享數據

我們知道如果線程之間沒有共享數據那么就不會有線程安全問題,我們使用的鎖、信號量、條件變量等其實都是用來保護共享數據的,比如鎖通常是用來包括臨界區的,臨界區中的代碼操作的就是線程共享數據;信號量使用的一個經典場景就是生產者消費者問題,生產者線程以及消費者線程都會操作同一個隊列,這里的隊列就是共享數據。

沿著這個思路開始找在兩個線程中都使用到的共享數據,果不其然,在一個角落中發現了這樣一段代碼: 

  1. auto* pb = global->mutable_obj(); 

這是分配protobuf對象的一段代碼,protobuf是Google開發是一種類似于JSON、XML的技術,因此常用于網絡通信和數據交換等場景,比如RPC等。

如果你不了解protobuf也沒有關系,實際上上面的這段代碼的要做的事情是這樣的: 

  1. if (global->obj == NULL) {  
  2.   global->obj = new obj();  
  3.  
  4. return global->obj; 

值得注意的是這段代碼現在會在兩個線程中執行,顯然問題就出現在了這里。

那么問題是怎么出現的呢?

我們假設有兩個線程,線程A和線程B,當這樣一段代碼在線程AB中同時執行時可能會有以下場景:

  •  線程A拿到global->obj并檢測到此時的global->obj為空,因此決定為其分配內存,但不巧的是此時發生線程切換,線程A在為global->obj分配內存前被暫停運行,如下所示: 
  1. if (global->obj == NULL) {  
  2.     <------- 線程切換,線程A被暫停執行   
  3.     global->obj = new obj();  
  4.  
  5. return global->obj; 
  •  線程A被暫停運行后線程B開始執行,這段代碼同樣會在線程B中執行一遍,因此線程B會首先檢查global->obj發現為空,因此為global->obj分配內存,分配完內存后發生線程切換,線程B被暫停運行,如下所示: 
  1. if (global->obj == NULL) {  
  2.     global->obj = new obj();  
  3.     <------- 線程切換,線程B被暫停執行   
  4.  
  5. return global->obj; 
  • 線程B被暫停運行后調度器決定重新運行線程A,此時線程A開始從被中斷的地方繼續運行,還記得線程A是從哪里被中斷的嗎,沒錯,就是在為global->obj分配內存前被中斷的,此時線程A繼續運行,也就是說global->obj = new obj()這段代碼又被執行了一次,雖然線程B已經為global->obj分配了內存。

Oops,典型的內存泄漏,線程B分配的內存再也無法被正常釋放掉了。

至此,我們已經找到了問題的原因,罪魁禍首就是共享數據,關鍵的一點是要意識到你的線程會隨時被中斷執行,CPU會隨時切換到其它線程。

代碼修復也非常簡單,再新增一個變量,兩個線程不在使用共享數據,到這里問題就解決了,從發現問題到完成修復耗時大概4小時。

經驗教訓

代碼的并行化重構是一件非常棘手的任務,很容易出現線程安全問題,解決線程安全問題首先要考慮的不是要不要加鎖,而是多個線程是否真的有必要使用共享數據,沒有必要的話多個線程操作私有數據根本就不會出現線程安全問題。

當出現線程安全問題時,第一時間重點排查線程使用的共享數據。

內存泄漏檢測工具

雖然這些沒有使用檢測工具全靠人肉debug其實還是因為問題排查范圍比較小,如果我們根本就不知道問題出現在了那次代碼改動那么檢測工具就非常重要了,在這里簡單介紹一下valgrind的使用,詳細的介紹請參考官方文檔。

假設有這樣一段問題代碼: 

  1. #include <stdlib.h>  
  2. void f(void)    
  3.  
  4.    int* x = malloc(10 * sizeof(int));  
  5.    x[10] = 0;        // 問題1: 越界  
  6. }                    // 問題2: 內存泄漏,x沒有被釋放掉   
  7. int main()   
  8.  
  9.    f();  
  10.    return 0;  

這段代碼中有兩個問題:一個是數據的越界訪問;另一個是內存泄漏。將該程序編譯為myprog。

接下來使用valgrind來檢查該程序,使用以下命令: 

  1. valgrind --leak-check=yes myprog 

運行完成后valgrind會給出檢測報告,關于程序越界訪問會給出這樣的輸出: 

  1. ==19182== Invalid write of size 4  
  2. ==19182==    at 0x804838F: f (example.c:6)  
  3. ==19182==    by 0x80483AB: main (example.c:11)  
  4. ==19182==  Address 0x1BA45050 is 0 bytes after a block of size 40 alloc'd  
  5. ==19182==    at 0x1B8FF5CD: malloc (vg_replace_malloc.c:130) 
  6. ==19182==    by 0x8048385: f (example.c:5)  
  7. ==19182==    by 0x80483AB: main (example.c:11) 

第一行告訴你代碼中存在Invalid write,也就是無效的寫,并給出了問題出現的位置。

關于內存泄漏問題會給出這樣的輸出: 

  1. ==19182== 40 bytes in 1 blocks are definitely lost in loss record 1 of 1  
  2. ==19182==    at 0x1B8FF5CD: malloc (vg_replace_malloc.c:130)  
  3. ==19182==    by 0x8048385: f (example.c:5)  
  4. ==19182==    by 0x80483AB: main (example.c:11) 

這里第一行報告了內存"definitely lost",也就是說一定會存在內存泄漏,并給出了問題出現的位置。

實際上除了"definitely lost",valgrind還會給出"probably lost"的報告,這兩種報告的含義是這樣的:

  •  "definitely lost":你的程序一定存在內存泄漏問題,修復。
  •  "probably lost":你的程序看起來像是有內存泄漏,有可能你在使用指針完成一些特定操作,因此不一定100%存在問題。

總結

編寫正確的多線程代碼從來不是一件容易的事情,線程安全問題的根源在于共享資源,因此在使用共享資源前務必確認我們一定要用共享資源嗎? 

 

責任編輯:龐桂玉 來源: C語言與C++編程
相關推薦

2022-09-28 10:35:31

JavaScript代碼內存泄漏

2020-12-15 10:52:44

CIO企業網

2024-02-21 08:00:55

WindowsDWM進程

2025-05-06 15:31:17

陶哲軒AI工具

2022-07-08 09:43:24

攜程酒店數據接口服務平臺

2025-07-09 03:00:00

2010-04-02 10:29:02

CentOS安裝

2024-01-30 10:12:00

Java內存泄漏

2012-08-03 09:51:55

程序員編程

2012-07-04 14:40:37

Ajax

2017-01-05 19:34:06

漏洞nodejs代碼

2018-10-25 15:24:10

ThreadLocal內存泄漏Java

2024-03-22 13:31:00

線程策略線程池

2019-11-20 15:02:45

Java虛擬機內存

2016-11-24 15:54:06

androidJSONObject

2012-06-05 00:26:58

程序員

2019-05-09 14:42:41

安吉智能倉庫

2010-09-26 15:38:33

JVM內存泄漏

2023-03-17 07:44:24

IntelDDR4內存

2022-05-31 06:07:45

Excel表Python
點贊
收藏

51CTO技術棧公眾號

亚洲成精国产精品女| 久久99国产乱子伦精品免费| 亚洲电影免费观看高清完整版在线| 国产精品无码免费专区午夜| 秋霞网一区二区| 美女尤物久久精品| www.亚洲男人天堂| 麻豆短视频在线观看| 中文字幕在线看片| 亚洲欧美怡红院| 成人午夜影院在线观看| 亚洲婷婷综合网| 日韩精品2区| 精品国产a毛片| 男人搞女人网站| 男女视频在线| 日本一二三不卡| 亚洲伊人一本大道中文字幕| 伊人手机在线视频| 亚洲国产精品日韩专区av有中文| 亚洲精品成a人在线观看| 一区二区三区入口| 岛国毛片av在线| 国产精品三级久久久久三级| 国产在线精品一区| 国产女18毛片多18精品| 性欧美暴力猛交另类hd| 欧美www在线| 精品无码人妻一区二区免费蜜桃| 精品午夜av| 欧美视频你懂的| 91精品国产91久久久久麻豆 主演| 福利在线午夜| 91污片在线观看| 亚洲一区二区三| 真实新婚偷拍xxxxx| 亚洲深夜激情| 久久免费国产视频| 国产一二三区精品| 日本在线电影一区二区三区| 国产午夜精品麻豆| 制服丝袜在线第一页| 日日狠狠久久| 欧美唯美清纯偷拍| 无码日韩人妻精品久久蜜桃| 国产极品人妖在线观看| 最近日韩中文字幕| 亚洲精品不卡| av天在线观看| 国产欧美日产一区| 日本免费一区二区三区| 亚洲人成色777777老人头| 国产成人亚洲综合a∨猫咪| 国产欧美va欧美va香蕉在线| 69视频免费看| 爽爽淫人综合网网站| 日本sm极度另类视频| 日本少妇性生活| 好看的日韩av电影| 久久久久久久久久国产| 欧美日韩精品在线观看视频| 亚洲一区在线| 久久国产精彩视频| 国产67194| 欧美日本国产| 欧美精品国产精品日韩精品| 动漫精品一区一码二码三码四码| 午夜精品999| 欧美激情免费在线| 精品亚洲永久免费| 亚洲看片一区| 欧美最顶级丰满的aⅴ艳星| 亚洲黄色小说图片| 美女视频一区免费观看| 国产精品久久久久久久久久三级| 中文字幕黄色片| 日韩和的一区二区| 国产精品中文字幕久久久| 中文字幕人妻一区二区在线视频| 热久久久久久久| 91精品免费看| 亚洲精品久久久蜜桃动漫| 成人免费高清在线| 女同一区二区| 麻豆网在线观看| 一区二区三区丝袜| 日本免费不卡一区二区| 欧美大片高清| 这里只有精品电影| 最新日本中文字幕| 神马影视一区二区| 久久久999国产精品| 久久精品无码人妻| 久热国产精品| 91影视免费在线观看| 免费观看a视频| 国产亚洲女人久久久久毛片| 成年人三级视频| 日韩精品极品视频免费观看| 国产欧美日韩中文| 在线免费观看高清视频| 国产一区二区三区日韩| 国产91免费视频| 日av在线播放| 最近中文字幕一区二区三区| 国产一区二区三区在线播放免费观看 | 日韩在线观看a| 美女露胸视频在线观看| 欧美性感一类影片在线播放| av在线天堂网| 成人亚洲一区二区| 久久人人爽人人| 中文字幕无线码一区| 粉嫩嫩av羞羞动漫久久久| 欧美日韩国产免费一区二区三区 | www一区二区| 中文字幕在线亚洲三区| 麻豆理论在线观看| 欧美福利视频一区| 精品人妻一区二区三区香蕉| 亚洲乱码精品| 国产成一区二区| 黄片毛片在线看| 亚洲欧美综合网| 国产精品免费观看久久| 亚洲一区 二区| x99av成人免费| 日韩欧美成人一区二区三区| 国产高清亚洲一区| 亚洲午夜精品久久久中文影院av| 国产直播在线| 日韩欧美亚洲一区二区| 日韩欧美在线视频播放| 性久久久久久| 国内精品视频免费| 欧美四级在线| 欧美精品一卡二卡| www在线观看免费视频| 99精品国产一区二区青青牛奶 | 超碰cao国产精品一区二区| 最新日韩中文字幕| 国产中文字幕视频| av亚洲产国偷v产偷v自拍| 亚洲区成人777777精品| 日本在线中文字幕一区二区三区| 日韩av中文字幕在线播放| 欧美日韩人妻精品一区二区三区| 九九**精品视频免费播放| 色综合视频二区偷拍在线| 欧美黑人一区| 亚洲欧美制服第一页| 91视频免费网址| 99久久伊人网影院| 九色自拍视频在线观看| 久本草在线中文字幕亚洲| 欧美激情伊人电影| 亚洲xxx在线| 一区二区三区久久| 日本少妇一级片| 欧美大片专区| 成人免费看片网址| 黑人精品视频| 亚洲第一精品夜夜躁人人爽 | 色婷婷亚洲综合| 精品无码国产污污污免费网站| 美女91精品| 亚洲高清视频一区二区| 狂野欧美性猛交xxxx| 日韩视频亚洲视频| 国产人妻精品一区二区三区| 一区二区三区在线视频播放 | 久久综合九色综合久久久精品综合| 日韩一级性生活片| 91亚洲无吗| 韩国v欧美v日本v亚洲| 五月天婷婷在线观看| 色综合久久久久综合体| 91资源在线播放| 激情丁香综合五月| www.在线观看av| 婷婷成人综合| 国产精品久久久久免费a∨| 日韩免费啪啪| 精品久久久久久久久久久院品网 | 亚洲六月丁香色婷婷综合久久 | 91九色成人| 欧美日韩国产成人在线观看| 少妇av在线播放| 色琪琪一区二区三区亚洲区| 亚洲一二三在线观看| 国产成人av一区| 国模吧无码一区二区三区| 欧美一级本道电影免费专区| 成人一区二区电影| 嗯啊主人调教在线播放视频 | 国产噜噜噜噜噜久久久久久久久 | 国产精品久久久国产盗摄| 亚洲国产aⅴ成人精品无吗| 三级电影在线看| 久久成人久久鬼色| 欧美午夜小视频| 欧美视频免费| 国产精品久久国产三级国电话系列| 波多野结衣久久精品| 日韩视频一区在线| 亚洲av毛片成人精品| 欧美日韩久久久久久| 久久久久久久久久久网| 国产欧美精品一区aⅴ影院| 欧美69精品久久久久久不卡 | 亚洲欧美电影一区二区| www.色多多| 国产裸体歌舞团一区二区| 97xxxxx| 精品999成人| 在线观看成人av电影| 欧美天堂影院| 超碰97在线人人| 国产精品久久久久久久久免费高清 | 午夜精品毛片| 日韩精品电影网站| 精品国产影院| 91亚洲国产成人精品性色| 日韩大尺度黄色| 久久久久成人网| 久久bbxx| 丝袜一区二区三区| 可以直接在线观看的av| 亚洲成av人乱码色午夜| 亚洲天堂手机在线| 色狠狠桃花综合| 国产专区第一页| 亚洲国产中文字幕在线视频综合| 亚洲一级二级片| 国产视频一区二区在线| 精品影片一区二区入口| 国产经典欧美精品| 中文字幕资源在线观看| 青椒成人免费视频| 免费观看成人网| 免费在线成人| 亚洲午夜无码av毛片久久| 极品少妇一区二区三区| 肉大捧一出免费观看网站在线播放 | a级黄色免费视频| 中文字幕乱码一区二区免费| 免费毛片视频网站| 久久色在线视频| 亚洲第九十七页| a级高清视频欧美日韩| 涩视频在线观看| 国产aⅴ综合色| 911亚洲精选| 成人黄色av网站在线| 怡红院一区二区| eeuss影院一区二区三区| aaa黄色大片| 不卡区在线中文字幕| 久久久午夜精品福利内容| 99在线精品一区二区三区| 香港三日本8a三级少妇三级99| 不卡高清视频专区| 午夜一区二区三区免费| 久久久777精品电影网影网| 无码人妻精品一区二区中文| 国产色91在线| 男人天堂资源网| 亚洲少妇30p| 久久久久久久久久久久国产| 精品久久久久久久久国产字幕| 日韩黄色a级片| 欧美性猛xxx| 中文天堂在线资源| 7777精品伊人久久久大香线蕉| 国产女人高潮的av毛片| 精品国产乱码久久久久久牛牛| 手机看片1024国产| 亚洲精品综合久久中文字幕| 成人在线二区| 美女av一区二区| 91九色在线播放| 国产成人一区二| www欧美在线观看| 国产美女精品久久久| 免费成人av| 这里只有精品66| 欧美视频久久| 国产日韩一区二区在线观看| 麻豆91在线观看| 美女露出粉嫩尿囗让男人桶| 久久综合狠狠综合久久激情 | 一级女性全黄久久生活片免费| 国产精品美女毛片真酒店| 色欧美片视频在线观看| 国产又黄又大又爽| 亚洲国内精品在线| 18视频免费网址在线观看| 欧美激情2020午夜免费观看| 日韩性xxx| 98国产高清一区| 国产一区99| 国产精品视频二| 噜噜噜91成人网| 日韩av加勒比| 91一区二区三区在线观看| 殴美一级黄色片| 欧美日韩日本国产| 99re只有精品| 亚洲午夜小视频| 欧美极品少妇videossex| 国产精品黄色影片导航在线观看| 777久久精品| 综合国产精品久久久| 先锋a资源在线看亚洲| 日本一本在线视频| 国产欧美一区二区精品忘忧草 | 欧美综合天天夜夜久久| 精品久久无码中文字幕| 一区二区三区www| 7777kkk亚洲综合欧美网站| 国产中文日韩欧美| 亚洲综合福利| 久久国产午夜精品理论片最新版本| 蜜臀a∨国产成人精品| 免费看黄色aaaaaa 片| 一区二区三区小说| 国产一区二区网站| 一本色道久久综合狠狠躁篇怎么玩 | 日本精品福利视频| 免费黄网站欧美| 国产精品揄拍100视频| 亚洲午夜久久久久| 99精品久久久久久中文字幕| 日韩在线观看免费网站| 亚洲天堂1区| 欧美在线一区二区三区四区| 亚洲午夜伦理| 韩国三级在线看| 亚洲精品免费一二三区| 91国在线视频| 丝袜亚洲另类欧美重口| 国产伊人久久| 一区二区三区视频| 日韩av午夜在线观看| 国产呦小j女精品视频| 五月激情综合婷婷| 日韩在线视频第一页| 欧美高清在线视频观看不卡| 韩国三级成人在线| 992tv成人免费观看| 国产在线不卡视频| 日本黄色小说视频| 日韩一区二区视频| 色黄网站在线观看| 国产精品99久久久久久久| 欧美日韩一区二区国产| 亚洲熟妇一区二区| 亚洲亚洲精品在线观看| 亚洲欧美另类一区| 97婷婷大伊香蕉精品视频| 欧美影院天天5g天天爽| 欧美 激情 在线| 国产欧美精品在线观看| 中文字幕+乱码+中文乱码91| 最近2019年手机中文字幕| 9999精品视频| 国产成人亚洲综合无码| 99视频热这里只有精品免费| 久久久久久久久久久久久av| 亚洲天堂精品在线| 久久人体av| 日本一道在线观看| 99精品黄色片免费大全| 国产免费一级视频| 色婷婷**av毛片一区| 国产一区二区三区国产精品| 男人添女人下部视频免费| 成人动漫视频在线| 天堂网免费视频| 日韩专区在线观看| 中文一区二区三区四区| 日韩少妇内射免费播放| 国产拍揄自揄精品视频麻豆| 97免费观看视频| 97在线精品视频| japanese国产精品| 亚洲最大视频网| 色哟哟国产精品免费观看| 人人干在线视频| 国产原创精品| 久久国产视频网| 国产又大又黑又粗免费视频| 国产一区二区三区在线视频| 欧美三级一区| 成熟老妇女视频| 曰韩精品一区二区| 男人av在线| www.成人av.com| 日韩不卡一二三区| 国产无码精品在线播放|