1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        Golang分析內(nèi)存溢出

        共 2998字,需瀏覽 6分鐘

         ·

        2022-06-21 00:51

           大家好,我是Z哥。


        最近系統(tǒng)在壓測過程中發(fā)現(xiàn)有一個程序在壓力增大后會內(nèi)存溢出。正好之前自己對 Golang 里分析 dump 這塊還沒怎么涉及,借此契機(jī)學(xué)習(xí)一下。

        網(wǎng)上搜了很多資料,發(fā)現(xiàn) Golang 好像沒有手動創(chuàng)建 dump 文件的方式(像 Java 的 jmap,.Net 的創(chuàng)建轉(zhuǎn)儲文件這種)。

        要么通過設(shè)置環(huán)境變量,在程序 crash 的時候自動創(chuàng)建 dump 文件,要么程序里 import 一個 pprof 的 package,實(shí)時分析 dump 相關(guān)的信息。

        如果有哪位老司機(jī)知道手動創(chuàng)建 dump 的方式,請?jiān)谠u論區(qū)教下大家,感謝~

        下面我手把手教大家如何通過以上兩種方式來分析內(nèi)存溢出問題,步驟詳細(xì),包教包會,建議收藏~


        /01  通過 pprof 實(shí)時分析/

        pprof 全稱是 performance profiles,是 google 官方提供的性能分析工具,項(xiàng)目地址:https://github.com/google/pprof。配合 Graphviz 使用可以提供圖形化的能力。

        使用它的方式很簡單,配合 pprof 庫來使用。只要在代碼里增加兩塊代碼。一塊是 import:
        _ "net/http/pprof"

        另一塊是main函數(shù)的開頭部分
        go func() {    http.ListenAndServe("0.0.0.0:8899", nil)  //ip和端口可以更換}()

        然后就可以在瀏覽器里輸入 http://localhost:8899/debug/pprof/ 看到相關(guān)的性能維度


        上圖中框出的這 4 個部分應(yīng)該是平時最常用的,從上往下分別是:

        1. 阻塞分析。比如,goroutine 的 wait。

        2. 內(nèi)存分析。比如,內(nèi)存泄漏、內(nèi)存消耗異常等情況。

        3. 互斥鎖分析。比如,觀察代碼里用到的 sync.RWMutex 和 sync.Mutex 的具體情況。

        4. CPU 分析。比如,排查哪些代碼較多地占用了 CPU 資源。


        雖然直接在瀏覽器頁面上也能看到一些信息,但是用來分析是不夠的,想要真正能分析問題還得通過前面提到的 pprof 工具。

        使用 go tool pprof 分析數(shù)據(jù),有兩種方式:

        • 通過url。go tool pprof  http://localhost:8899/debug/pprof/profile

        • 通過文件。go tool pprof cpuprofile  文件路徑



        好了,我們來試一下。

        Z哥寫了一段消耗內(nèi)存的代碼,如下:
        func main() {  go func() {    http.ListenAndServe("0.0.0.0:8899", nil)  }()    str := "sadasdasffrgrgrgrgrgrfefafasfsadasdasffrgrgrgrgrgrfefafasfsadasdasffrgrgrgrgrgrfefafasfsadasdasffrgrgrgrgrgrfefafasfsadasdasffrgrgrgrgrgrfefafasfsadasdasffrgrgrgrgrgrfefafasf"  for i := 0; i < 999; i++ {    str += str  }    fmt.Scanln()}

        在 web 頁面點(diǎn)擊「heap」入口,我們可以看到實(shí)時內(nèi)存的使用情況。


        然后我們再通過以下命令進(jìn)入到命令交互模式看看效果:

        go tool pprof http://localhost:8899/debug/pprof/heap

        進(jìn)去之后輸入「top」,就能很直觀的看到哪個方法占用了內(nèi)存。


        這里的幾個列的含義簡單羅列下:

        1. flat:當(dāng)前函數(shù)所占用的容量。

        2. flat%:當(dāng)前函數(shù)所占用的容量,在總分配容量的百分比。

        3. sum%:是從調(diào)用的最外層到當(dāng)前方法累加使用的容量占總?cè)萘康陌俜直?/span>

        4. cum:當(dāng)前函數(shù)以及子函數(shù)所占用的容量。

        5. cum%:當(dāng)前函數(shù)以及子函數(shù)所占用的容量,在總分配容量的百分比。

        6. 最后一列是函數(shù)的名字


        我們可以再輸入獲得更詳細(xì)的信息:

        list main.main



        每一行代碼占用了多少容量直接給你羅列出來了,是不是很香。


        分析其他的也是類似的,比如以下是分析 CPU 的。



        /02 程序 crash 的時候自動創(chuàng)建 dump 文件/
         
        大多數(shù)時候,我們可能沒有條件實(shí)時分析程序運(yùn)行情況。比如問題在生產(chǎn)環(huán)境偶發(fā)出現(xiàn),且無法在測試環(huán)境重現(xiàn)。

        這個時候我們可以配置當(dāng)程序 crash 的時候自動保存 dump 文件。

        先輸入命令「ulimit -a」看下當(dāng)前是否開啟了core file。


        如果是0的話說明未開啟。可以通過:

        ulimit -c 1024  或者 ulimit -c unlimited 來設(shè)置 dump 文件的最大 size。

        這里的數(shù)字單位是 block,具體需要根據(jù)所在的操作系統(tǒng)一個 block 對應(yīng)的大小來設(shè)置。

        如果你想讓這個設(shè)置永久生效那么需要將它添加到 /.profile 中

        echo "ulimit -c unlimited" >> ~/.profile


        再看下 Golang 的環(huán)境變量 GOTRACEBACK 的設(shè)置是什么,

        export


        如果不是 crash 或者不存在 GOTRACEBACK 的環(huán)境變量(默認(rèn)是 none)的話,改成 crash。

        export GOBACTRACE=crash


        這就意味著,讓程序發(fā)生 crash 的時候會自動生成 dump 文件。(Z哥在 mac 系統(tǒng)上運(yùn)行沒能自動生成 dump 文件,但在 centos 上可以)

        然后運(yùn)行的程序如果發(fā)生 panic,會自動生成 dump 文件在程序運(yùn)行的目錄下。


        紅框圈出來的是它的默認(rèn)文件名的格式。

        同unlimited 一樣,也需要讓這個設(shè)置永久生效的話,需要添加到/.profile中:

        echo "export GOTRACEBACK=crash " >> ~/.profile


        有了 dump 文件,你就可以用 gdb 或者 delve 工具來分析了(官方更建議我們使用 delve,對 Golang 的支持更好,這里就先不展開了。

        一般來說,建議大家如果在本地環(huán)境的話使用 pprof 就好了,如果在服務(wù)器上,務(wù)必開始 crash 自動保存 dump 的功能,便于后續(xù)的快速定位問題并分析。


        好了,這篇呢,Z 哥和你分享了在 Golang 中分析運(yùn)行時的代碼問題。主要有兩種途徑:

        • 通過 pprof 實(shí)時分析。

        • 程序 crash 時自動保存 dump,再通過 delve 或者 gdb 分析。


        希望對你有所幫助。建議收藏,以防不備之需~


        往期推薦



        手撕 Golang 高性能內(nèi)存緩存庫 bigcache! #4 


        是什么讓 Golang 如此受歡迎?語言創(chuàng)造者的回顧


        一文告訴你Go 1.19都有哪些新特性

        想要了解Go更多內(nèi)容,歡迎掃描下方?? 關(guān)注 公眾號,回復(fù)關(guān)鍵詞 [實(shí)戰(zhàn)群]  ,就有機(jī)會進(jìn)群和我們進(jìn)行交流~

        分享、在看與點(diǎn)贊,至少我要擁有一個叭~

        瀏覽 73
        點(diǎn)贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報
        評論
        圖片
        表情
        推薦
        點(diǎn)贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            东京热一区二区 | 中文字幕一区二区三区四区50岁 | 长腿校花无力呻吟娇喘的视频 | 孙头退休后日女儿的幸福生活 | 国产熟女精品 | 看女被强伦轩视频 | 狠狠干香蕉| 狠狠二区 | 欧美丝袜足交视频 | www.911国产 |