亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何分析Unsafe的CAS和內存操作的原理

發布時間:2021-12-03 18:48:17 來源:億速云 閱讀:233 作者:柒染 欄目:云計算

如何分析Unsafe的CAS和內存操作的原理,相信很多沒有經驗的人對此束手無策,為此本文總結了問題出現的原因和解決方法,通過這篇文章希望你能解決這個問題。

Java 語言的一大特點就是跨平臺,并且提供的有一套完美的內存管理機制。但這都是 JVM 提供的,如果我們想要直接訪問系統內存資源、自主管理內存資源等就無法實現。于是 Java 又提供了一個魔法類:Unsafe。

Unsafe 類位于 sun.misc 包中。從名字看,這個類就是一個不安全的類,實際上它確實是封裝了一些不安全的操作!

Unsafe 類和 String 類一樣的被定義為 final,也就是說它不可以被繼承。并且 Unsafe 被設計成了單例,構造函數是私有的,只能通過 getUnsafe 方法獲得它。除此之外,getUnsafe 方法還設置了限制條件,只有授信的代碼才能獲得該類的實例。哪些是授信的代碼呢?當然是 JDK 庫里面的類是可以隨意使用的。

如何分析Unsafe的CAS和內存操作的原理

說了半天,這個類,我們無法使用,你講它又何意義?

別急,Java 雖然不建議我們使用它,但是我們還是可以通過兩種方式來使用它。

第一種方式是:讓我們的代碼在啟動時“授信”。在運行程序時,指定 bootclasspath 選項,讓你使用 Unsafe 實例的類被引導類加載器加載,從而通過 Unsafe.getUnsafe 方法安全的獲取 Unsafe 實例。

如何分析Unsafe的CAS和內存操作的原理

這個做法比較少用,所以推薦大家采用第二種方法:通過反射來使用它。

如何分析Unsafe的CAS和內存操作的原理

注意有的 IDE 可能支持的不是很友好。比如:eclipse 顯示”Access restriction…”錯誤,但如果你運行代碼,它將正常運行。如果這個錯誤提示令人煩惱,可以通過以下設置來避免:

如何分析Unsafe的CAS和內存操作的原理

Unsafe 有 8 大功能,很多號主只講了它的 CAS 功能。

如何分析Unsafe的CAS和內存操作的原理  

如上圖所示,Unsafe 提供的 105 個 API 大致可分為內存操作、CAS、Class 相關、對象操作、線程調度、系統信息獲取、內存屏障、數組操作等。今天我先來說兩個大功能:CAS 和內存操作(和我前面的《手把手教你通過Java代碼體驗強引用、軟引用、弱引用、虛引用的區別》、《90%的程序員可能都不了解的堆外內存》都有些關聯,這是一個系列)。

CAS 操作主要涉及到下面 3 個 API。

如何分析Unsafe的CAS和內存操作的原理

CAS 即比較并替換,實現并發算法時常用到的一種技術。CAS 操作包含三個操作數——內存位置、預期原值及新值。執行 CAS 操作的時候,將內存位置的值與預期原值比較,如果相匹配,那么處理器會自動將該位置值更新為新值,否則,處理器不做任何操作。我們都知道,CAS 是一條 CPU 的原子指令(cmpxchg 指令),不會造成所謂的數據不一致問題,Unsafe 提供的 CAS 方法(如 compareAndSwapXXX)底層實現即為 CPU 指令 cmpxchg。

CAS 在 java.util.concurrent.atomic 相關類、Java AQS、CurrentHashMap 等實現上有非常廣泛的應用。比如,在 AtomicInteger 的實現中,靜態字段 valueOffset 即為字段 value 的內存偏移地址,valueOffset 的值在 AtomicInteger 初始化時,在靜態代碼塊中通過 Unsafe 的 objectFieldOffset 方法獲取。在 AtomicInteger 中提供的線程安全方法中,通過字段 valueOffset 的值可以定位到 AtomicInteger 對象中 value 的內存地址,從而可以根據 CAS 實現對 value 字段的原子操作。

如何分析Unsafe的CAS和內存操作的原理  

比如,下圖就為某個 AtomicInteger 對象自增操作前后的內存示意圖,對象的基地址 baseAddress=“0x110000”,通過 baseAddress+valueOffset 得到 value 的內存地址 valueAddress=“0x11000c”;然后通過 CAS 進行原子性的更新操作,成功則返回,否則繼續重試,直到更新成功為止。

如何分析Unsafe的CAS和內存操作的原理  

說完 CAS,我們再來說說 Unsafe 的內存操作。

內存操作主要有下面 9 個 API。

如何分析Unsafe的CAS和內存操作的原理

在《手把手教你通過Java代碼體驗強引用、軟引用、弱引用、虛引用的區別》和《90%的程序員可能都不了解的堆外內存》兩篇文章中,我已經講過了。在 Java 中創建的對象都處于堆內內存(heap)中,堆內內存是由 JVM 所管控的 Java 進程內存,并且它們遵循 JVM 的內存管理機制,JVM 會采用垃圾回收機制統一管理堆內存。與之相對的是堆外內存,存在于 JVM 管控之外的內存區域,Java 中對堆外內存的操作,依賴于 Unsafe 提供的操作堆外內存的 native 方法。

使用堆外內存的原因是:

  • 對垃圾回收停頓的改善。由于堆外內存是直接受操作系統管理而不是 JVM,所以當我們使用堆外內存時,即可保持較小的堆內內存規模。從而在 GC 時減少回收停頓對于應用的影響。

  • 提升程序 I/O 操作的性能。通常在 I/O 通信過程中,會存在堆內內存到堆外內存的數據拷貝操作,對于需要頻繁進行內存間數據拷貝且生命周期較短的暫存數據,都建議存儲到堆外內存。

我前面提到的 DirectByteBuffer,在 Netty、MINA 等 NIO 框架中應用廣泛。DirectByteBuffer 對于堆外內存的創建、使用、銷毀等邏輯均由 Unsafe 提供的堆外內存 API 來實現。

如何分析Unsafe的CAS和內存操作的原理  

上圖為 DirectByteBuffer 構造函數,創建 DirectByteBuffer 的時候,通過 Unsafe.allocateMemory 分配內存、Unsafe.setMemory 進行內存初始化,而后構建 Cleaner 對象用于跟蹤 DirectByteBuffer 對象的垃圾回收,以實現當 DirectByteBuffer 被垃圾回收時,分配的堆外內存一起被釋放。具體的釋放就是我前面講的 PhantomReference 虛引用。

看完上述內容,你們掌握如何分析Unsafe的CAS和內存操作的原理的方法了嗎?如果還想學到更多技能或想了解更多相關內容,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

灵宝市| 外汇| 宁德市| 密云县| 无锡市| 龙泉市| 伊川县| 南陵县| 肥东县| 阿荣旗| 五台县| 清水县| 确山县| 庐江县| 于田县| 年辖:市辖区| 彰化市| 德阳市| 乌兰浩特市| 喀喇| 阳高县| 岳阳市| 彭水| 吕梁市| 临邑县| 庆云县| 原阳县| 绩溪县| 文安县| 北川| 荥经县| 昔阳县| 白河县| 平利县| 盈江县| 项城市| 明水县| 安国市| 西青区| 常德市| 泾川县|