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

不同內(nèi)存管理方式的聰明程度大 PK

存儲(chǔ) 存儲(chǔ)軟件
代碼要在計(jì)算機(jī)上跑起來,需要一系列計(jì)算機(jī)資源:內(nèi)存、網(wǎng)絡(luò)端口、打開的文件等等,這些資源一起被叫做進(jìn)程。

[[429396]]

代碼要在計(jì)算機(jī)上跑起來,需要一系列計(jì)算機(jī)資源:內(nèi)存、網(wǎng)絡(luò)端口、打開的文件等等,這些資源一起被叫做進(jìn)程。

進(jìn)程有一個(gè)專門的控制塊來記錄這些資源,叫做進(jìn)程控制塊(PCB)。

這些資源里面最重要的就是內(nèi)存了,進(jìn)程啟動(dòng)的時(shí)候會(huì)向操作系統(tǒng)申請(qǐng)一些內(nèi)存。

如果內(nèi)存是無限的,那么我們?cè)谏厦娣艛?shù)據(jù)、代碼等,不用擔(dān)心不夠用,但可惜內(nèi)存是有限的,我們要把用不到的內(nèi)存及時(shí)的回收掉,用來放別的東西,這樣代碼才能正常的運(yùn)行。

內(nèi)存分為代碼區(qū)、全局?jǐn)?shù)據(jù)區(qū)、堆區(qū)、棧區(qū)等,這是操作系統(tǒng)可執(zhí)行文件的內(nèi)存模型,如果是 javascript、java 這種解釋型語(yǔ)言,那還會(huì)再做自己的一些劃分。但總體來說,都是分為這幾部分。

代碼區(qū)的內(nèi)容基本不變。

棧區(qū)存放隨著函數(shù)調(diào)用而聲明的局部變量,每個(gè)函數(shù)一個(gè)棧幀,它是有上限的,調(diào)用層次過深會(huì)棧溢出。

全局?jǐn)?shù)據(jù)區(qū)存放全局變量。

棧區(qū)和全局?jǐn)?shù)據(jù)區(qū)中的大對(duì)象會(huì)存放在堆上,只留一個(gè)引用。

堆區(qū)存放動(dòng)態(tài)分配的大對(duì)象,占內(nèi)存最多,我們內(nèi)存管理也主要是管理堆內(nèi)存。

為了管理好這一畝三分地的堆內(nèi)存,不同的語(yǔ)言有不同的方式,聰明程度各不相同,我們來看一下誰(shuí)更聰明吧:

C、C++

C、C++ 的內(nèi)存都是程序員手動(dòng)管理的,比如 C++ 的 class 有構(gòu)造函數(shù)和析構(gòu)函數(shù),構(gòu)造函數(shù)里申請(qǐng)內(nèi)存,析構(gòu)函數(shù)里面就把這些內(nèi)存釋放掉。

是否漏掉一些內(nèi)存沒釋放取決于程序員,很看程序員水平。

騰訊之前是大規(guī)模用 C++ 做服務(wù)端開發(fā)的,但是后來也逐漸轉(zhuǎn)向 go、java 了,因?yàn)?C++ 這種手動(dòng)管理內(nèi)存的方式,萬(wàn)一某個(gè)程序員漏掉了一些內(nèi)存沒釋放,那就內(nèi)存泄漏了。(內(nèi)存泄漏就是不再使用的內(nèi)存一直占用著,導(dǎo)致可用內(nèi)存減少),而服務(wù)器是長(zhǎng)時(shí)間跑的,輕微的內(nèi)存泄漏逐漸積累最終都會(huì)導(dǎo)致進(jìn)程崩潰。

靠程序員來保證釋放掉不用的內(nèi)存太難了,如果程序能自己回收這些垃圾內(nèi)存就好了,那就解放了程序員了,代碼可靠性也更高。所以后來的高級(jí)語(yǔ)言基本都有了自動(dòng)的垃圾回收機(jī)制。

java、javascript

c++ 那種手動(dòng)管理內(nèi)存的方式太麻煩了,所以 java 和 javascript 設(shè)計(jì)之初就不讓程序員操作內(nèi)存,而是自己做了一套垃圾回收機(jī)制,定期把沒用的內(nèi)存釋放下。

怎么檢測(cè)哪些內(nèi)存沒用呢?最開始的思路是對(duì)每個(gè)對(duì)象都記錄下引用數(shù),如果沒有被引用了,那就可以回收了,這種思路叫引用計(jì)數(shù)。

但是這個(gè)思路有個(gè)問題,萬(wàn)一兩個(gè)對(duì)象你引用我我引用你,并且都沒被別的對(duì)象引用,這種循環(huán)引用的問題檢查不出來。

看來這種方式還不夠聰明。怎么優(yōu)化呢?

從全局的對(duì)象開始,把所有引用的對(duì)象標(biāo)記一遍,沒被標(biāo)記的就清掉。這樣不管是沒被引用的,還是循環(huán)引用但是都沒被別的對(duì)象引用的,都可以檢查出來,這種思路叫做標(biāo)記清除。

標(biāo)記清除的思路更聰明些,所以現(xiàn)在的 js 引擎基本都用這個(gè)思路。

這樣的內(nèi)存管理思路其實(shí)也是存在問題的,萬(wàn)一有的不用的對(duì)象被放到全局了,那就永遠(yuǎn)不會(huì)回收了。這種也會(huì)內(nèi)存泄漏。

這個(gè)只能靠程序員排查了,通過工具把一些不該放到全局的變量給找出來。

js 的內(nèi)存泄漏排查一般都是用 chrome devtools 的 memory 工具,他可以取到某個(gè)時(shí)間點(diǎn)的內(nèi)存快照,做一些操作后,再取一次內(nèi)存快照,兩個(gè)內(nèi)存快照對(duì)比下就能找出增加了哪些全局變量。然后定位到那段內(nèi)存泄漏的代碼。

比如這樣一段代碼:

5s 后在全局聲明一個(gè)變量 aaa,是正則表達(dá)式類型。

我們用 chrome devtools 的 memory 工具分別取兩次快照。

這里有不同的視圖,我們選擇比較視圖來對(duì)比兩個(gè)快照:

可以看到 delta 那一列,顯示了正則表達(dá)式的對(duì)象 + 1,這就是我們定時(shí)器里聲明的那個(gè)全局變量。

通過這種內(nèi)存快照的對(duì)比,就可以定位什么操作導(dǎo)致的內(nèi)存泄漏,進(jìn)而定位到代碼。

自動(dòng)的垃圾回收避免了程序員沒有釋放一些內(nèi)存導(dǎo)致的泄漏,但是仍然會(huì)有把沒用的對(duì)象放到全局導(dǎo)致的泄漏。這種方案比較聰明,但也是有問題的。

rust

rust 也不需要程序員手動(dòng)管理內(nèi)存,但也沒有垃圾回收,卻把內(nèi)存管理的更好,而且能避免 99% 的內(nèi)存泄漏問題。它是怎么做到的呢?

rust 覺得堆中的對(duì)象之所以難管理就是因?yàn)楸惶嗟胤揭昧?,如果限制了?duì)象只能屬于某個(gè)函數(shù),只能有一個(gè)引用,別的引用自己復(fù)制一份去,這樣函數(shù)調(diào)用結(jié)束就可以把用到的堆中的對(duì)象全部回收了,根本不會(huì)留下垃圾。這種思路叫做所有權(quán)機(jī)制。

所有權(quán)機(jī)制通過限制對(duì)象的引用的方式來做到了不需要垃圾回收器也能很好的管理內(nèi)存。而且也沒有 js 那種不小心把對(duì)象放到全局就會(huì)內(nèi)存泄漏的問題。

rust 的所有權(quán)機(jī)制是更聰明的一種內(nèi)存管理方式,也是因?yàn)檫@個(gè)原因,rust 正變得越來越火。

總結(jié)

進(jìn)程的可用內(nèi)存是有限的,需要及時(shí)把不再用到的變量的內(nèi)存釋放掉,不同語(yǔ)言對(duì)內(nèi)存管理的方式不同,聰明程度不同:

c、c++ 是靠程序員自己管理內(nèi)存的,萬(wàn)一不小心某個(gè)內(nèi)存沒釋放就泄漏了。

java、javascript 則是不讓程序員自己管理,有專門的垃圾回收器,最開始通過引用計(jì)數(shù),后來改成了標(biāo)記清除,通過這種方式來找到?jīng)]用的內(nèi)存釋放掉。

但萬(wàn)一把沒用的對(duì)象放到了全局,那就回收不了了,這種就是內(nèi)存泄漏,需要用 chrome devtools 的 memory 工具記錄兩次快照,然后做 diff,通過看內(nèi)存是否增加來定位到導(dǎo)致內(nèi)存泄漏的代碼。

rust 也不用程序員手動(dòng)管理內(nèi)存,但也沒有垃圾回收器,它限制了對(duì)象只能有一個(gè)引用,這樣函數(shù)調(diào)用結(jié)束就可以把對(duì)象回收掉,根本不會(huì)留下垃圾,而且也避免了把沒用的對(duì)象放到全局的那種內(nèi)存泄漏(因?yàn)橹辉试S一個(gè)引用)。

 

語(yǔ)言的發(fā)展規(guī)律就是這樣,讓程序員做的事情更少,也讓程序的健壯性更高。這需要更聰明的語(yǔ)言設(shè)計(jì),更強(qiáng)大的編譯器/解釋器。

 

責(zé)任編輯:武曉燕 來源: 神光的編程秘籍
相關(guān)推薦

2009-12-25 17:15:03

Linux內(nèi)存

2025-04-15 06:00:00

2013-03-14 10:28:52

管理人才管理管理方式

2015-03-16 12:49:56

虛擬化

2019-03-14 15:00:48

混合云云計(jì)算管理

2010-09-30 11:55:03

DB2表空間

2011-02-25 14:00:15

ProFTPD

2010-02-04 15:41:10

C++內(nèi)存管理

2010-03-18 10:45:43

網(wǎng)管交換機(jī)

2010-01-21 17:15:22

可網(wǎng)管交換機(jī)

2017-01-04 13:27:43

SD-WANSDN網(wǎng)絡(luò)

2012-03-12 09:39:38

大數(shù)據(jù)IT資源

2024-11-27 09:58:41

Spring模塊化管理方式

2021-02-24 14:26:05

人工智能機(jī)器學(xué)習(xí)數(shù)據(jù)

2009-07-29 09:29:33

無線網(wǎng)絡(luò)接入方式

2010-01-08 16:58:49

網(wǎng)管交換機(jī)

2011-01-27 10:57:54

北塔網(wǎng)絡(luò)管理運(yùn)維管理

2018-11-08 15:21:59

2010-01-05 14:38:36

網(wǎng)管交換機(jī)
點(diǎn)贊
收藏

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