Linux下的Nginx內(nèi)存泄露定位
有同事報(bào)他的機(jī)器上nginx存在內(nèi)存泄露,都吃了4G內(nèi)存沒法忍了,于是趕緊查一查。
問題定位
1、先top -u work 查看進(jìn)程內(nèi)存占用情況,確認(rèn)確實(shí)是占了4G沒法忍了(下圖只是整理文檔時補(bǔ)的示例)。

2、ps -ef | grep nginx | grep -v grep | grep work
查看nginx進(jìn)程確認(rèn)是業(yè)務(wù)的nginx的某個worker子進(jìn)程疑似存在內(nèi)存泄露占了大量內(nèi)存。
3、發(fā)現(xiàn)只有部分worker進(jìn)程占用內(nèi)容很大,并不是全部。cat error.log定位為什么不是worker進(jìn)程都內(nèi)存增大,只是個別worker進(jìn)程內(nèi)存占用很大?

4、發(fā)現(xiàn)并不是那個子進(jìn)程沒有內(nèi)存泄露,而是那個子進(jìn)程頻繁被kill,然后master又重啟新的子進(jìn)程。
通過:dmesg | grep pid ,查看系統(tǒng)日志。確認(rèn)那些內(nèi)存占用低的worker進(jìn)程是被oom kill了,然后被master又重啟新的子進(jìn)程。

5、確定是指定進(jìn)程內(nèi)存泄露后,查看該進(jìn)程的內(nèi)存分配,定位泄露信息。
①.通過 pmap -x pid dump出該進(jìn)程的內(nèi)存分配,確認(rèn)確實(shí)存在超大塊內(nèi)存分配。

②.通過 cat /proc/pid/smaps查看內(nèi)存段的具體起始位置。

③.通過gdb dump出那段內(nèi)存存儲內(nèi)容。
gdb -p 42102
dump binary memory ./memory2.log 0x7fa1d0b57000 0x7FA1D0B70000

④.查看dump出的內(nèi)容,發(fā)現(xiàn)是一個業(yè)務(wù)研發(fā)的nginx擴(kuò)展存儲的內(nèi)容,確認(rèn)是該擴(kuò)展錯在內(nèi)容泄露。
問題明確后,具體修復(fù)問題就簡單了,對應(yīng)擴(kuò)展修復(fù)問題后重新上線完成修復(fù)。
Linux進(jìn)程內(nèi)存分析常用工具命令
**top:**查看機(jī)器整體內(nèi)存使用情況和各進(jìn)程內(nèi)存使用情況
**RES:**常駐內(nèi)存,一般比較關(guān)心這個
**SHR:**共享內(nèi)存
**VIRT:**虛擬內(nèi)存
**DATA:**數(shù)據(jù)占用內(nèi)存
**pmap:**pmap -x pid dump 進(jìn)程的內(nèi)存分配情況
**mtrace:**可以跟蹤記錄進(jìn)程的內(nèi)存分配
**gdb -p pid:**連接到進(jìn)程
**cat /proc/pid/smaps:**查看內(nèi)存塊具體開始結(jié)束位置
**dump binary memory ./out.log 0x7fa1d0b57000 0x7FA1D0B70000:**dump出指定位置存儲的內(nèi)容
mtrace-內(nèi)存使用追蹤(內(nèi)存)
1. 函數(shù)格式: mtrace 用于開啟內(nèi)存使用記錄,muntrace用于取消內(nèi)存使用記錄。內(nèi)存使用情況記錄到一個文件,值由環(huán)境變量:MALLOC_TRACE決定。 2. 范...