Linux 記憶體洩漏了,我該如何定位和處理?

2021-10-23 23:10:07 字數 1566 閱讀 2661

對普通程序來說,能看到的其實是核心提供的虛擬記憶體,這些虛擬記憶體還需要通過頁表,由系統對映為物理記憶體。

當程序通過 malloc()申請虛擬記憶體後,系統並不會立即為其分配物理記憶體,而是在首次訪問時,才通過缺頁異常陷入核心中分配記憶體。

為了協調 cpu與磁碟間的效能差異,linux 還會使用cache和buffer,分別把檔案和磁碟讀寫的資料快取到記憶體中。

對應用程式來說,動態記憶體的分配和**,是既核心又複雜的乙個邏輯功能模組。管理記憶體的過程中,也很容易發生各種各樣的"事故",比如

今天帶你來看看,記憶體洩漏到底是怎麼發生的,以及發生記憶體洩漏之後該如何排查和定位。說起記憶體洩漏,這就要先從記憶體的分配和**說起了。記憶體的分配和**

先回顧一下,你還記得應用程式中,都有哪些方法來分配記憶體嗎?用完後,又該怎麼釋放還給系統呢?

前面講程序的記憶體空間時,我曾經提到過,使用者空間記憶體包括多個不同的記憶體段,比如唯讀段、資料段、堆、棧以及檔案對映段等。這些記憶體段正是應用程式使用記憶體的基本方式。

舉個例子,你在程式中定義了乙個區域性變數,比如乙個整數陣列 int data[64],就定義了乙個可以儲存64個整數的記憶體段。由於這是乙個區域性變數,它會從記憶體空間的棧中分配記憶體。

棧記憶體由系統自動分配和管理。一旦程式執行超出了這個區域性變數的作用域,棧記憶體就會被系統自動**,所以不會產生記憶體洩漏的問題。

再比如,很多時候,我們事先並不知道資料大小,所以你就要用到標準庫函式malloc(),在程式中動態分配記憶體。這時候,系統就會從記憶體空間的堆中分配記憶體。

堆記憶體由應用程式自己來分配和管理。除非程式退出,這些堆記憶體並不會被系統自動釋放,而是需要應用程式明確呼叫庫函式 free來釋放它們。如果應用程式沒有正確釋放堆記憶體,就會造成記憶體洩漏。

這是兩個棧和堆的例子,那麼,其他記憶體段是否也會導致記憶體洩漏呢? 經過我們前面的學習,這個問題並不難回答。

記憶體洩漏的危害非常大,這些忘記釋放的記憶體,不僅應用程式自己不能訪問,系統也不能把它們再次分配給其他應用。記憶體洩漏不斷累積,甚至會耗盡系統記憶體。

雖然,系統最終可以通過oom(out of memory)機制殺死程序,但程序在oom前,可能已經引發了一連串的反應,導致嚴重的效能問題。比如,其他需要記憶體的程序,可能無法分配新的記憶體,記憶體不足,又會觸發系統的快取**以及swap機制,從而進一步導致 i/o的效能問題等等。

比如,其他需要記憶體的程序,可能無法分配新的記憶體,記憶體不足,又會觸發系統的快取**以及swap機制從而進一步導致 i/o的效能問題等等。

記憶體洩漏的危害這麼大,那我們應該怎麼檢測這種問題呢? 特別是,如果你已經發現了記憶體洩漏,該如何定位和處理呢。

接下來,我們就用乙個計算斐波那契數列的案例,來看看記憶體洩漏問題的定位和處理方法。斐波那契數列是乙個這樣的數列∶0、1、1、2、3、5、8也就是除了前兩個數是0和1,其他數都由前面兩數相加得到,用數學公式來表示就是f(n)=f(n-1)+f(n-2),(n>=2),f(o)=0, f(1)=1。

記憶體洩漏了,該如何定位

程序的使用者空間記憶體包括了多個不同的記憶體段,比如唯讀段 資料段 堆 棧 以及檔案對映等,這些記憶體段是應用程式使用記憶體的基本方式。比如再程式中定義乙個區域性變數,int data 64 就定義了乙個可以儲存64個整數的記憶體段,由於是區域性變數,會從記憶體空間的棧中分配。記憶體洩漏的危害非常大...

C 該如何記憶體洩漏檢測

mfc每乙個cpp都有以下內容 ifdef debug define new debug new endif 而debug new這個巨集定義在afx.h中,就是它幫助我們解決這個問題這樣如果洩露就可以通過輸出視窗看見。其中最重要的乙個是在標頭檔案中包含crtdbg.h 然後呼叫 crtdumpme...

Linux記憶體洩漏如何檢測

記憶體洩漏一般情況下是指從堆中申請的記憶體沒有釋放。應用程式呼叫malloc,realloc,new函式從堆中申請一塊記憶體,在使用完畢後,需要呼叫free new來釋放記憶體。如果缺少釋放,就會導致記憶體洩漏。久而久之,整個系統的記憶體將會慢慢耗盡。那我們該如何及時發現記憶體洩漏呢?review階...