自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

徹底理解內(nèi)存泄漏,Memory leak

存儲(chǔ) 存儲(chǔ)軟件
有很多情況會(huì)導(dǎo)致這一問(wèn)題,像重復(fù)使用的某個(gè)結(jié)構(gòu)體/對(duì)象,當(dāng)再次復(fù)用時(shí)沒(méi)有清理上一次使用遺留的數(shù)據(jù)、系統(tǒng)中存在cache,但cache的過(guò)期策略設(shè)置不得當(dāng)?shù)鹊取?/div>

[[442166]]

大家好,我是小風(fēng)哥,今天和大家聊一聊內(nèi)存泄漏這個(gè)話題。

我之前寫(xiě)過(guò)好幾篇關(guān)于內(nèi)存的文章,在這些文章講到內(nèi)存申請(qǐng)時(shí)我很喜歡用停車場(chǎng)來(lái)做類比,內(nèi)存申請(qǐng)就好比去停車場(chǎng)找停車位,找到停車位后你就可以把車停在這里。

從這個(gè)類比看什么是內(nèi)存泄漏呢?內(nèi)存泄漏看上去是停車場(chǎng)的車輛只進(jìn)不出導(dǎo)致最終找不到停車位,從程序員的角度看就是內(nèi)存只申請(qǐng)取不釋放,如果你去問(wèn),可能有不少人認(rèn)為內(nèi)存泄漏就是這么回事。

然而這其實(shí)是不全面的。

申請(qǐng)過(guò)多內(nèi)存

首先內(nèi)存只申請(qǐng)不釋放未必就是內(nèi)存泄漏,有可能是你的程序的確需要申請(qǐng)很多內(nèi)存,這是正常的,然而如果是bug導(dǎo)致申請(qǐng)了很多內(nèi)存,這就是內(nèi)存泄漏了,或者也有人將其稱為space leak,意思是申請(qǐng)的內(nèi)存超過(guò)了正常所需;不管是有意無(wú)意,總之在這種情況下你依然保持對(duì)這些內(nèi)存的引用,因此你總可以找到這些內(nèi)存并刪除它們,就看你刪不刪。

有很多情況會(huì)導(dǎo)致這一問(wèn)題,像重復(fù)使用的某個(gè)結(jié)構(gòu)體/對(duì)象,當(dāng)再次復(fù)用時(shí)沒(méi)有清理上一次使用遺留的數(shù)據(jù)、系統(tǒng)中存在cache,但cache的過(guò)期策略設(shè)置不得當(dāng)?shù)鹊取?/p>

內(nèi)存無(wú)法刪除

另一類比較有趣的內(nèi)存泄漏是說(shuō)你申請(qǐng)了一些內(nèi)存,但最終卻沒(méi)有什么指向它們:

  1. void memory_leak() { 
  2.   char* mem = (char*)malloc(1024); 
  3.   // just return 

在這段代碼中我們申請(qǐng)了1k內(nèi)存,然而當(dāng)memory_leak函數(shù)返回后你就再也不知道這段內(nèi)存到底在哪里了!

用停車場(chǎng)的示例來(lái)說(shuō)就是有些司機(jī)太過(guò)土豪,家里的車太多以至于把將車放在停車場(chǎng)這件事忘掉了,導(dǎo)致這些車根本就不會(huì)有人再開(kāi)走,因此白白浪費(fèi)停車位,并導(dǎo)致可用車位越來(lái)越少,而對(duì)于編程來(lái)說(shuō)就是粗心大意的程序員申請(qǐng)了一些內(nèi)存后最終“忘掉”了,再也不會(huì)有什么東西(變量/指針)指向這些內(nèi)存,因此在這種情況下你沒(méi)有辦法再找到這些內(nèi)存并將其刪除。

內(nèi)存碎片

這也算的上是一類特殊的內(nèi)存泄漏,用停車場(chǎng)的例子來(lái)說(shuō)就是兩個(gè)停車位中間??苛艘惠v小型老年代步車,導(dǎo)致盡管這兩個(gè)停車位剩余的空間足夠大但又恰好都沒(méi)有辦法再停靠一輛小汽車。

假定我們系統(tǒng)中寶貴的內(nèi)存大小只有8字節(jié),其中有兩個(gè)字節(jié)已經(jīng)分配出去了,就像這樣:

現(xiàn)在,系統(tǒng)中空閑的內(nèi)存是6字節(jié),下一次的內(nèi)存申請(qǐng)需要分配5字節(jié),糟糕,我們已經(jīng)沒(méi)有辦法再找到連續(xù)的5個(gè)字節(jié)大小的內(nèi)存空間了,盡管全部空間的內(nèi)存還有6字節(jié),這就是所謂的內(nèi)存碎片問(wèn)題。

而對(duì)于內(nèi)存分配器來(lái)說(shuō)如果出現(xiàn)這種情況那么將不得不借助操作系統(tǒng)的幫助來(lái)擴(kuò)大堆區(qū),因此看起來(lái)我們的程序占據(jù)的內(nèi)存越來(lái)越多,盡管實(shí)際上程序可能并不需要那么多內(nèi)存,僅僅是因?yàn)閮?nèi)存碎片的原因?qū)е乱徊糠謨?nèi)存無(wú)法被再次被利用起來(lái)。

然而對(duì)于現(xiàn)代操作系統(tǒng)尤其具備虛擬內(nèi)存能力的系統(tǒng)來(lái)說(shuō),內(nèi)存碎片問(wèn)題通??赡懿⒉粫?huì)和我們想象的那樣嚴(yán)重,原因就在于分配的內(nèi)存只需要在虛擬地址空間上連續(xù)而不必在物理內(nèi)存上也連續(xù),假定我們?cè)谔摂M內(nèi)存地址空間需要存放“aabbccdd”這樣的字符串,在虛擬地址空間上看這是連續(xù)的就像這樣:

但在物理內(nèi)存上可能是這樣存放的:

可以看到,利用虛擬內(nèi)存我們可以更加充分靈活的利用“邊邊角角”的物理內(nèi)存,從而減少內(nèi)存碎片帶來(lái)的影響。

關(guān)于虛擬內(nèi)存更詳細(xì)的講解你可以參考《深入理解操作系統(tǒng)》虛擬內(nèi)存一章,關(guān)于公眾號(hào)“碼農(nóng)的荒島求生”并回復(fù)“操作系統(tǒng)”即可。

如果你的程序需要重復(fù)申請(qǐng)很多對(duì)象/數(shù)據(jù)/結(jié)構(gòu)體,并在最后一次性全部釋放,那么內(nèi)存池是一個(gè)避免內(nèi)存碎片不錯(cuò)的選擇,原理在于盡管從內(nèi)存池的角度看會(huì)有碎片,但當(dāng)我們以內(nèi)存池大小為單位從堆區(qū)中申請(qǐng)釋放內(nèi)存時(shí),這種碎片將不復(fù)存在。

關(guān)于內(nèi)存池你可以參考這篇《高性能服務(wù)器內(nèi)存池是如何實(shí)現(xiàn)的》。

內(nèi)存泄漏帶來(lái)的問(wèn)題

在現(xiàn)代操作系統(tǒng)中除非你的程序運(yùn)行時(shí)間足夠長(zhǎng)或者申請(qǐng)的內(nèi)存足夠快足夠多否則內(nèi)存泄漏可能并不是什么大問(wèn)題,你甚至可能都察覺(jué)不出來(lái)有內(nèi)存泄漏,因?yàn)楫?dāng)進(jìn)程運(yùn)行結(jié)束后其占據(jù)的內(nèi)存會(huì)被操作系統(tǒng)收回,在這種情況下你可能不必過(guò)于關(guān)心這個(gè)問(wèn)題,但對(duì)于長(zhǎng)時(shí)間運(yùn)行的服務(wù)器端程序、數(shù)據(jù)庫(kù)程序、操作系統(tǒng)等,內(nèi)存泄漏就屬于比較嚴(yán)重的問(wèn)題了,因?yàn)檫@些程序必須時(shí)刻在線,任何微小的內(nèi)存泄漏在時(shí)間的加持下都會(huì)非常明顯。

內(nèi)存持續(xù)泄漏會(huì)發(fā)生什么?

如果內(nèi)存持續(xù)泄漏那么你的電腦可能會(huì)爆炸。。。這。。。當(dāng)然是不可能的。

你的系統(tǒng)會(huì)慢到炸是有可能的。

內(nèi)存的申請(qǐng)速度會(huì)對(duì)系統(tǒng)性能產(chǎn)生很大的影響,當(dāng)系統(tǒng)內(nèi)存不足時(shí),內(nèi)存分配器找到一塊滿足要求的空閑內(nèi)存塊將更加困難耗時(shí)更多,當(dāng)程序消耗的內(nèi)存超過(guò)物理內(nèi)存大小時(shí)虛擬內(nèi)存系統(tǒng)(如果有的話)開(kāi)始發(fā)揮作用,將進(jìn)程地址空間中不常用的一部分swap出去,此時(shí)系統(tǒng)性能將快速下降,表現(xiàn)出來(lái)的就是程序員運(yùn)行變慢、卡頓。

當(dāng)然,根據(jù)系統(tǒng)配置,像Linux系統(tǒng),可能會(huì)將消耗內(nèi)存很多的進(jìn)程kill掉,這就是Out of Memory killer,簡(jiǎn)稱oom killer。

內(nèi)存泄漏檢測(cè)工具

不像程序崩潰Core dump,這類問(wèn)題通過(guò)debug通常能獲取一些線索,但內(nèi)存泄漏問(wèn)題就沒(méi)那么直接了,尤其對(duì)于C/C++程序來(lái)說(shuō),這時(shí)我們將不得不借助必要的工具。

那么我們?cè)摾檬裁吹墓ぞ邅?lái)解決內(nèi)存泄漏問(wèn)題呢?下一篇文章將給你答案。

這個(gè)公眾號(hào)里所有的文章都已經(jīng)匯總在了Github上,地址https://github.com/xfenglu/everycodershouldknow ,你也可以點(diǎn)擊左下方“閱讀原文”直達(dá),歡迎訪問(wèn),求star,哈哈。

本文轉(zhuǎn)載自微信公眾號(hào)「碼農(nóng)的荒島求生」,可以通過(guò)以下二維碼關(guān)注。轉(zhuǎn)載本文請(qǐng)聯(lián)系碼農(nóng)的荒島求生技術(shù)公眾號(hào)。

 

責(zé)任編輯:武曉燕 來(lái)源: 碼農(nóng)的荒島求生
相關(guān)推薦

2014-07-30 14:22:41

AndroidWebView內(nèi)存泄漏

2024-02-02 09:00:14

內(nèi)存泄漏對(duì)象

2011-08-19 14:27:29

iPhone開(kāi)發(fā)

2024-03-11 08:22:40

Java內(nèi)存泄漏

2023-12-18 10:45:23

內(nèi)存泄漏計(jì)算機(jī)服務(wù)器

2021-05-13 08:55:33

Android架構(gòu)功能

2012-02-22 21:28:58

內(nèi)存泄漏

2015-03-30 11:18:50

內(nèi)存管理Android

2021-08-09 09:54:37

內(nèi)存泄漏JS 阿里云

2021-08-05 15:28:22

JS內(nèi)存泄漏

2019-11-07 10:37:36

CookieSessionToken

2019-01-09 08:31:07

2019-06-11 14:45:25

2020-03-03 14:15:49

Redis持久化數(shù)據(jù)庫(kù)

2024-03-15 08:23:26

異步編程函數(shù)

2020-06-08 09:18:59

JavaScript開(kāi)發(fā)技術(shù)

2019-01-30 18:24:14

Java內(nèi)存泄漏編程語(yǔ)言

2017-11-09 16:07:00

Web應(yīng)用內(nèi)存

2024-01-30 10:12:00

Java內(nèi)存泄漏

2018-12-07 10:52:08

內(nèi)存泄漏方法
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)