要理解為什么將 ArrayBuffer 和 SharedArrayBuffer 添加到 JavaScript 中,你需要了解一些關(guān)于內(nèi)存管理的內(nèi)容。 你可以將機(jī)器中的內(nèi)存看作一堆盒子。就像你在辦公室里的郵箱,或是小孩子們使用的收納箱。 如果你想要為其他孩子留下一些東西,你可以把它放在一個(gè)盒子里。 在每個(gè)盒子旁邊都有一個(gè)數(shù)字,這些數(shù)字就是內(nèi)存地址,用來(lái)告訴別人在哪里找到你留給他們的東西。 這些盒子中的每一個(gè)都具有相同的尺寸,并且可以容納一定量的信息。盒子的尺寸取決于機(jī)器。這個(gè)大小稱為字長(zhǎng)。它通常是32位或64位。但是為了顯示方便,這里我們使用8位字長(zhǎng)。 如果我們想把數(shù)字2放在其中一個(gè)盒子中,我們可以很容易地做到這一點(diǎn)。數(shù)字很容易轉(zhuǎn)換成二進(jìn)制。 如果我們想要的東西不是數(shù)字怎么辦?比如字母 H? 我們需要一個(gè)類似UTF-8的編碼來(lái)用數(shù)字代替這些東西。而為了把這些東西轉(zhuǎn)換成數(shù)字,我們需要一個(gè)類似編碼器環(huán)的工具。之后我們就可以存儲(chǔ)它了。 當(dāng)我們想把它從盒子里拿出來(lái)的時(shí)候,必須通過(guò)解碼器把它轉(zhuǎn)換回 H。 自動(dòng)內(nèi)存管理當(dāng)你在使用 JavaScript 時(shí),實(shí)際上并不需要考慮內(nèi)存。內(nèi)存被抽象出來(lái),你不會(huì)直接接觸到它。 取而代之的是 JS 引擎充當(dāng)中介,為你管理內(nèi)存。 比如說(shuō)有一段 JS 代碼用來(lái)創(chuàng)建一個(gè)變量(假設(shè)該 JS 代碼使用了 React)。 JS 引擎利用編碼器把該值轉(zhuǎn)換成二進(jìn)制。 它將在內(nèi)存中找到可以容納該二進(jìn)制的空間,這個(gè)過(guò)程稱為分配內(nèi)存。 然后,引擎將跟蹤該變量是否仍然可以從程序中的任何地方訪問(wèn)。如果該變量無(wú)法再訪問(wèn),以便 JS 引擎可以在回收的內(nèi)存中存放新的值。 這種在內(nèi)存中監(jiān)控變量(字符串、對(duì)象或其他類型)并釋放掉不再使用的變量所占用的內(nèi)存的過(guò)程,稱為垃圾回收。 像 JavaScript 這樣不直接處理內(nèi)存的語(yǔ)言被稱為內(nèi)存管理語(yǔ)言。 這種自動(dòng)內(nèi)存管理可以使開(kāi)發(fā)人員更輕松。但它也增加了一些開(kāi)銷,而這種開(kāi)銷有時(shí)會(huì)使性能不可預(yù)測(cè)。 手動(dòng)內(nèi)存管理和自動(dòng)管理內(nèi)存的語(yǔ)言相比,需要手動(dòng)管理內(nèi)存的語(yǔ)言有些不同。例如,我們來(lái)看看 React 如何使用 C 語(yǔ)言寫(xiě)入內(nèi)存(現(xiàn)在可以通過(guò)WebAssembly來(lái)實(shí)現(xiàn))。 C 語(yǔ)言沒(méi)有 JavaScript 在內(nèi)存上的抽象層。而是直接在內(nèi)存上運(yùn)行。你可以從內(nèi)存加載東西,也可以將內(nèi)容存儲(chǔ)到內(nèi)存中。 當(dāng)你將 C 語(yǔ)言或其他語(yǔ)言編譯到 WebAssembly 時(shí),你使用的工具將在 WebAssembly 中添加一些輔助代碼。例如,它會(huì)添加用于編碼和解碼字節(jié)的代碼。這些代碼稱為運(yùn)行環(huán)境。運(yùn)行環(huán)境會(huì)處理一些本該 JS 引擎做的事情。 但是對(duì)于手動(dòng)管理的語(yǔ)言,其運(yùn)行時(shí)將不包括垃圾回收。 這并不意味著你完全要自己處理。即使在手動(dòng)內(nèi)存管理的語(yǔ)言中,通常會(huì)從語(yǔ)言運(yùn)行時(shí)獲得一些幫助。例如,在 C 語(yǔ)言中,運(yùn)行時(shí)會(huì)把哪些內(nèi)存地址可用記錄在一張表中,這張表叫做空閑列表。 你可以使用函數(shù) 你必須弄清楚何時(shí)調(diào)用這些函數(shù)。這就是為什么它被稱為手動(dòng)內(nèi)存管理——你得自己管理內(nèi)存。 作為一名開(kāi)發(fā)人員,弄清楚何時(shí)清除不同部分的內(nèi)存可能很難。如果你在錯(cuò)誤的時(shí)間進(jìn)行操作,可能會(huì)出現(xiàn)bug,甚至導(dǎo)致安全漏洞。如果你不這樣做,你的內(nèi)存就會(huì)耗盡。 這就是為什么許多現(xiàn)代語(yǔ)言使用自動(dòng)內(nèi)存管理的原因——避免人為錯(cuò)誤。但這是以性能為代價(jià)的。 我將在下一篇文章中更多地解釋這一點(diǎn)。 |
|