Java內(nèi)存模型

在網(wǎng)上很多資料都介紹了java內(nèi)存模型的內(nèi)容,可看的資料越多,導(dǎo)致自己越迷糊了,到底什么是Java內(nèi)存模型,Java內(nèi)存模型是用來(lái)干嘛的,接下來(lái)就和大家一起探討Java內(nèi)存模型到底是個(gè)啥?

說(shuō)到Java內(nèi)存模型,先得介紹一下什么是模型。拿最簡(jiǎn)單的小時(shí)候玩的飛機(jī)模型來(lái)說(shuō),它讓我們了解了什么是飛機(jī),飛機(jī)大概是個(gè)什么樣的,它的機(jī)艙在哪,駕駛室在哪等等...

理解了這一點(diǎn),相信你對(duì)模型就基本上有一個(gè)大概的了解了。那么我們接下來(lái)就開始介紹什么是內(nèi)存模型。同樣的,內(nèi)存模型是用來(lái)抽象對(duì)計(jì)算機(jī)內(nèi)存進(jìn)行操作的一個(gè)理想化的概念。

首先介紹一個(gè)理想化的內(nèi)存模型,這也是程序員最期待看到的一個(gè)內(nèi)存模型 - 順序一致性內(nèi)存模型。這個(gè)內(nèi)存模型的概念比較簡(jiǎn)單,即我們寫了一段程序(圖1-1),我們期待程序按照我們的寫的內(nèi)容執(zhí)行,即先執(zhí)行第1步,接下來(lái)依次執(zhí)行2、3、4步,這就是最簡(jiǎn)單也是最理想化的模型,順序一致性內(nèi)存模型,這種模型更容易理解,我們?cè)趯懘a時(shí)執(zhí)行的過(guò)程中,能“看”到的也是這種理論化的模型的執(zhí)行結(jié)果。

1-1

順序一致性內(nèi)存模型為程序的開發(fā)者和使用者提供了方便,但是,對(duì)于計(jì)算機(jī)而言,它卻限制太多,以至于使計(jì)算機(jī)的性能不能充分發(fā)揮。相對(duì)于我們看到的順序一致性模型而言,計(jì)算機(jī)更傾向于“優(yōu)化”我們代碼的執(zhí)行順序,如圖1-1中,第3步依賴于第1步和第2步的執(zhí)行結(jié)果,但是第1步和第2步本身沒有依賴關(guān)系,因此,計(jì)算機(jī)內(nèi)存在讀寫的過(guò)程中,就可能先執(zhí)行第2步,然后執(zhí)行第1步。也就是說(shuō),計(jì)算機(jī)基于單線程程序中不改變程序的運(yùn)行結(jié)果,來(lái)對(duì)我們代碼的執(zhí)行順序進(jìn)行優(yōu)化。

那么計(jì)算機(jī)是如何優(yōu)化我們的程序呢?

在討論計(jì)算機(jī)如何優(yōu)化之前,我們首先要知道我們的程序?qū)?nèi)存主要做了什么操作:讀和寫。

因此,計(jì)算機(jī)針對(duì)內(nèi)存的讀和寫對(duì)我們的程序進(jìn)行如下優(yōu)化:

1)寫/讀操作的優(yōu)化:兩個(gè)不存在依賴關(guān)系的寫/讀操作可以進(jìn)行執(zhí)行順序的優(yōu)化

2)寫/寫操作的優(yōu)化:兩個(gè)不存在依賴關(guān)系的寫操作可以進(jìn)行執(zhí)行順序的優(yōu)化

3)讀/寫和讀/讀操作的優(yōu)化:兩個(gè)不存在依賴關(guān)系的讀/寫或讀/讀操作可以進(jìn)行執(zhí)行順序的優(yōu)化

首先介紹寫/讀的優(yōu)化。大部分內(nèi)存模型幾乎都會(huì)進(jìn)行這種優(yōu)化,簡(jiǎn)單理解方式為,寫比讀更消耗資源,因此,大部分的內(nèi)存模型都會(huì)將寫操作和讀操作的執(zhí)行順序進(jìn)行優(yōu)化(前提是寫/讀操作不存在依賴關(guān)系)【本質(zhì)上是因?yàn)橛?jì)算機(jī)使用了寫緩存,因此,進(jìn)行寫/讀的優(yōu)化能大幅度提升計(jì)算機(jī)的執(zhí)行效率】。如圖1-2中,第1步和第2步為寫操作,第3步為讀操作,計(jì)算機(jī)在執(zhí)行過(guò)程中執(zhí)行完第1步之后,可能會(huì)先執(zhí)行第3步(讀),再執(zhí)行第2步(寫),這就是最基本的寫/讀重排序(變?yōu)榱俗x/寫)。

1-2

接下來(lái)介紹寫/寫操作的優(yōu)化。寫寫操作的優(yōu)化比較容易理解,如上圖1-2中,由于第1步和第2步本身并沒有依賴關(guān)系,因此,內(nèi)存在寫入過(guò)程中,可能會(huì)先執(zhí)行第2步,再執(zhí)行第1步,這就是寫/寫操作的優(yōu)化。

最后介紹讀/寫和讀/讀操作的優(yōu)化。內(nèi)存在讀取變量和寫入變量的過(guò)程不存在依賴關(guān)系時(shí),如內(nèi)存先讀取a的值(第1步),然后再寫入b的值(第2步),由于這兩步本身沒有依賴關(guān)系,因此內(nèi)存可能會(huì)先執(zhí)行第2步,再執(zhí)行第1步。讀/讀操作的優(yōu)化類似【內(nèi)存讀取a的值(第1步),然后讀取b的值(第2步),由于1,2兩步?jīng)]有依賴關(guān)系,因此,計(jì)算機(jī)可能會(huì)重排序?yàn)橄葓?zhí)行第2步,再執(zhí)行第1步】。

以上就是有關(guān)Java內(nèi)存模型對(duì)于讀寫操作的優(yōu)化了,針對(duì)這四種優(yōu)化類型,整理了幾種抽象的內(nèi)存模型如下:

1)對(duì)于寫/讀操作放松的內(nèi)存模型:Total Store Ordering(簡(jiǎn)稱TSO)

2)在上一條基礎(chǔ)上,對(duì)于寫/寫操作放松的內(nèi)存模型:Partial Store Ordering(簡(jiǎn)稱PSO)

3)在前兩條基礎(chǔ)上,對(duì)于讀/寫和讀/讀放松的內(nèi)存模型:Relaxed Memory Ordering(簡(jiǎn)稱RMO)和powerPc

幾種內(nèi)存模型和他們對(duì)于讀/寫重排序的支持如下(圖1-3)

1-3

在單線程程序中,不論是哪一種內(nèi)存的優(yōu)化都不會(huì)影響最終結(jié)果的呈現(xiàn),這也是內(nèi)存模型建立的最基本原則,但是到了多線程程序中,由于各個(gè)線程間的操作相互不可見,因此,就可能會(huì)出現(xiàn)類變量讀/寫的問(wèn)題,具體問(wèn)題,我們?cè)谙乱徽?,并發(fā)編程之內(nèi)存間的“通話”一章中詳細(xì)介紹。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容