linux下的內存管理泄漏

 

  內存的管理

     在內存管理上份爲兩層,一個是線性區,類似於 00c73000-00c88000,對應於虛擬內存,它實際上不佔用實際物理內存;另外一個是具體的物理頁面,它對應我們機器上的物理內存。

         這裏要提到一個很重要的概念,內存的延遲分配/按需分配。Linux 內核在用戶申請內存的時候,只是給它分配了一個線性區(也就是虛存),並沒有分配實際物理內存;只有當用戶使用這塊內存的時候(比如malloc後,memset一個字節),內核纔會分配具體的物理頁面給用戶,這時候才佔用寶貴的物理內存。內核釋放物理頁面是通過釋放線性區,找到其所對應 的物理頁面,將其全部釋放的過程。

 

1.物理內存:

                   實際內存,常見的有8G  16G  32G  64G等

2.虛擬內存:

                   操作系統(windows或者linux)基於物理內存有限及內存操作效率考慮,設計了虛擬地址訪問機制,能夠分配比系統現有物理內存更多的內存。虛擬內存使用的是硬盤的空間,硬盤空間動輒幾十G上百G,運用了虛擬內存技術,即拿出一部分硬盤空間來充當內存使用,大幅提升了“可用” 內存的大小。(實際上,CPU還是讀取物理內存)。

         Linux下兩種主要Cache方式:Buffer Cache和Page Cache.前者Buffer Cache針對磁盤塊的讀寫,後者Page Cache針對文件等的讀寫。這些Cache有效縮短了I/O系統調用(比如 read,write,getdents)的時間
   兩個關鍵概念:
  2.1頁面調度
  頁面調度是指從磁盤向內存傳輸數據,以及相反的過程,這個過程之所以被稱爲頁面調度,是因爲Linux內存被平均劃分成大小相等的頁面;通常頁面大小爲 4KB和8KB(在Solaris中可以用pagesize命令查看)。當可執行程序開始運行時,它的映象會一頁一頁地從磁盤中讀入,與此類似,當某些內存在一段時間內空閒(不被使用),就可以把它們換出到交換空間中,這樣就可以把空閒的RAM交給其他需要它的程序使用。
  2.2交換
  交換的概念容易和頁面調度通混淆,頁面調度是指把一個進程所佔內存的空閒部分傳輸到磁盤上,而交換是指當系統中實際的內存已不夠滿足新的分配需求時,把整個進程傳輸到磁盤上,交換活動通常意味着內存不足。其中,交換空間是專門用於臨時存儲內存的一塊磁盤空間,通常在頁面調度和交換進程數據時使用。(linux下可配置 /proc/sys/vm/swappiness ,默認爲10,也就是達到90,既可以使用swap。看睡眠情況,一般不睡眠情況下,32G物理內存以上,則推薦爲8G的交換空間)

  程序操作內存

         系統函數brk mmap等實現的是直接操作內存,brk是通過移動最新的偏移地址得到內存(這個會存在內存空洞),而mmap是找空閒內存,而glic(ptmalloc)等運行庫爲了內存高效,會進行封裝:其多個小128k的內存申請釋放後,進行內存合併管理;大於128,用mmap進行直接操作內存,沒有合併管理一說。

         因此,可能存在代碼free,但是虛擬內存還是佔用的。

         對內存空洞要求高的話,建議使用tcmalloc。

  內存查看

1.top命令

        

【大致看下,容易有歧義,建議以free來查看內存情況】

【按(shift+M)會進行內存排序,關注下VIRT和res不要一直漲就可以了】

 

 

2.free

[root@scs-2 tmp]# free

                   total       used       free     shared    buffers     cached
Mem:            128        119           8          0            2               22    從OS的角度來看
-/+ buffers/cache:        95          32                                                             應用程序的內存
swap:          255            0         255

 

第2行-/+ buffers/cache:

-buffers/cache 的內存數: 95 (應用程序的內存,等於第1行的 used - buffers - cached)

+buffers/cache 的內存數:  32 (應用程序的內存,等於第1行的 free + buffers + cached)

可見-buffers/cache反映的是被程序實實在在喫掉的內存,+buffers/cache反映的是可以挪用的內存總數。

第三行數據是交換分區SWAP的,也就是我們通常所說的虛擬內存。 

 (mem)行是從OS的角度來看,因爲對於OS,buffers/cached 都是屬於被使用。

used     119 已用內存中包括內核(OS)使用+Application(X, oracle,等)使用的+buffers+cached.

         3.一個進程的內存

      我們通過free命令查看機器空閒內存時,會發現free的值很小。這主要是因爲,在Linux系統中有這麼一種思想,內存不用白不用,因此它儘可能的cache和buffer一些數據,以方便下次使用。但實際上這些內存也是可以立刻拿來使用的。

  所以 空閒內存=free+buffers+cached=total-used

 

  內存泄漏

         1.依據

         查看一個進程使用的內存,是一個很令人困惑的事情。因爲我們寫的程序,必然要用到動態鏈接庫,將其加入到自己的地址空間中,但是 / proc/pid/statm 統計出來的數據,會將這些動態鏈接庫所佔用的內存也簡單的算進來。

這樣帶來的問題,動態鏈接庫佔用的內存有些是其他程序使用時佔用的,卻算在了你這裏。你的程序中包含了子進程,那麼有些動態鏈接庫重用的內存會被重複計算。

       

 

         懷疑某處發生了內存泄露,可以查看該進程的maps表,看進程的堆段或者mmap段的虛擬地址空間是否持續增加,如果是,說明很可能發生了內存泄露,如果mmap段虛擬地址空間持續增加,還可以看到各個段的虛擬地址空間的大小,從而可以確定是申請了多大的內存,對調試內存泄露類問題可以起到很好的定位作用。Rss-Resident Set Size 實際使用物理內存(包含共享庫佔用的內存) 

 

 

學習鏈接

https://www.jianshu.com/p/38a4bcf564d5  內存機制,包括示例內存釋放

https://www.cnblogs.com/yangykaifa/p/7397497.html   mtrace 定位泄漏

https://testerhome.com/articles/20547    gdb定位泄漏

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章