JVM內存結構Java內存模型Java對象模型

悟空老師思維導圖:
https://naotu.baidu.com/file/60a0bdcaca7c6b92fcc5f796fe6f6bc9icon-default.png?t=N7T8https://naotu.baidu.com/file/60a0bdcaca7c6b92fcc5f796fe6f6bc9

1.JVM內存結構&&Java內存模型&&Java對象模型

1.1.JVM內存結構

1.2.Java對象模型

????????Java對象模型表示的是這個對象本身的存儲模型,JVM會給這個類創建一個instanceKlass保存在方法區,用來在JVM層表示該Java類,當在Java代碼中使用new創建一個對象時JVM會創建一個instanceOopDesc對象,這個對象中包含了對象頭以及實例數據;

1.3.Java內存模型(JMM)

1.3.1.為什么需要JMM?

? ? ? ? 1.C語言不存在內存模型概念;

? ? ? ? 2.Java程序依賴處理器,不同處理器結果不一樣;

? ? ? ? 3.無法保證并發安全;

1.3.2.什么是JMM?

? ? ? ? JMM是一組規范,需要各個JVM的實現來遵循JMM規范,以便開發者可以利用這些規范更方便的開發多線程程序;如果沒有這樣一個JMM內存模型來規范,那么很可能經過了不同JVM的不同規則的重排序后,導致不同虛擬機上運行的結果不一樣;JMM不僅僅作為一組規范它同時還是“工具類”、“synchronized”、“Lock”等的原理;

1.3.3.JMM核心內容

? ? ? ? 1.重排序

? ? ? ? 2.可見性

? ? ? ? 3.原子性

? ? ? ? 并發編程線程安全問題的根源在于:重排序、可見性;

1.3.3.1.重排序
1.3.3.1.1.什么是重排序

? ? ? ? 代碼在JVM中的執行順序和在Java代碼中的順序不一致;(代碼指令執行順序并不是嚴格按照語句順序執行的,這就是重排序);

1.3.3.1.2.重排序代碼案例
import java.util.concurrent.CountDownLatch;
/*** 演示代碼執行時被JVM重排序*/
public class OutOfOrderExecution{private static int x = 0,y = 0;private static int a = 0,b = 0;public static void main(String[] args) throws InterruptedException {// 計數器int i = 0;for(;;){i++;// 重置a = 0;b = 0;x = 0;y = 0;// 閘門CountDownLatch countDownLatch = new CountDownLatch(1);// 線程一Thread one = new Thread(new Runnable() {@Overridepublic void run() {try {countDownLatch.await();} catch (InterruptedException e) {e.printStackTrace();}a = 1;x = b;}});// 線程二Thread two = new Thread(new Runnable() {@Overridepublic void run() {try {countDownLatch.await();} catch (InterruptedException e) {e.printStackTrace();}b = 1;y = a;}});two.start();one.start();// 放開閘門countDownLatch.countDown();// 主線程等待子線程執行完成one.join();two.join();String result = "第:"+ i +"次" + "(" + x + "," + y + ")";if(x == 0 && y == 0){ // 說明:如上代碼出現x,y都等于0的情況說明代碼執行時被重排序了(即代碼并未按照編寫順序執行,而是被編譯器重排序了其執行順序大致為:y=a=0,x=b=0,b=1,a=1,)System.out.println("執行代碼被重排序了:" + result);break;}else {System.out.println(result);}}}
}

執行結果

1.3.3.1.3.重排序好處

1.3.3.1.4.重排序的三種情況

? ? ? ? 1.編譯器優化;

? ? ? ? 2.CPU指令重排;

? ? ? ? 3.內存的“重排序”

1.3.3.2.可見性
1.3.3.2.1.什么是“可見性”問題

? ? ? ? 可見性:指一個線程對共享變量的修改對于其它線程是可見的;

? ? ? ? 可見性問題:多線程并發訪問共享變量時,一個線程對共享變量的修改對于其它線程可能是不

??????????????????????????????可見的;

1.3.3.2.2.為什么會有“可見性”問題

????????因為CPU有多級緩存,導致某些線程讀取到的數據可能已經過期;如果所有CPU核心都只用一個緩存,那就不存在可見性問題;而實際情況是每個核心都會將需要的數據讀取到自己的“獨占緩存”中,數據修改后也是先寫入到自己的“獨占緩存”,然后等待刷新到“主存”(所有核心共享)中,在數據還未被刷新到“主存”時造成其它核心讀取到過期的數據值;

1.3.3.2.3.什么是happens-before

????????happens-before規則是用來解決“可見性”問題的,即在時間上動作A發生在動作B之前,B保證能看見A的所有操作這就是happens-before;

1.3.2.2.4.哪些運用了happens-before規則

? ? ? ? 1.單線程規則;

? ? ? ? 2.鎖操作(synchroniezd和Lock);

? ? ? ? 3.volatile變量;

? ? ? ? 4.線程啟動;

? ? ? ? 5.線程join;

? ? ? ? 6.傳遞性(hb代表happens-before;?如果hb(A,B),且hb(B,C)則可以推出hb(A,C)) ;

? ? ? ? 7.中斷(一個線程被其它線程interrupt,那么檢測中斷(IsInterrupted)或者拋出?

? ? ? ? ? ?InterruptedExcption一定能被其它線程看見);

? ? ? ? 8.構造方法(對象構造方法的最后一條指令,finalize()方法一定能看到)

? ? ? ? 9.工具類的happens-before原則

? ? ? ? ? ? ? ?9.1.線程安全的容器,如“ConcurrentHashMap”,get一定能看到之前的所有put操作;

? ? ? ? ? ? ? ? 9.2.CountDownLatch

? ? ? ? ? ? ? ? 9.3.Semaphore

? ? ? ? ? ? ? ? 9.4.Future

? ? ? ? ? ? ? ? 9.5.線程池

? ? ? ? ? ? ? ? 9.6.CyclicBarrier

1.3.3.3.原子性
1.3.3.3.1.什么是原子性

? ? ?一系列操作,要么全部執行成功,要么全部不執行或全部執行失敗,不會出現執行一半的情況,原子是不可分割的;

1.3.3.3.2.Java中的原子操作有哪些

1.除long和double之外的基本類型賦值操作(int,byte,boolean,short,char,float);

2.所有“引用”的賦值操作;

3.java.concurrent.Atomic.*包下所有類的原子操作;

備注:創建對象不是原子性操作!

1.創建對象操作不是原子性操作,其由三個操作構成(Singleton5 instance = new Singleton5(););1.1.創建一個空的instance;1.2.調用構造方法;1.3.將創建好的對象賦值給instance實例;
1.3.3.3.3.long和double原子性問題

? ? ? ? 對于32位的JVM long和double的操作不是原子的(32位JVM中會將long和double的一次寫入操作拆分成2個單獨的寫入操作),但是在64位的虛擬機上long和double的操作是原子的,在實際開發中商用的Java虛擬機已經處理了這個問題;我們自己也可以使用volatile去解決;

1.3.3.4.原子操作 + 原子操作 != 原子操作

? ? ? ? 簡單地把原子操作組合在一起并不能保證整體依然具有原子性;

1.4.synchronized可見性的正確理解

????????1.4.1.synchronized不僅保證了原子性還保證了可見性;

????????1.4.2.synchronized不僅讓被保護的代碼線程安全,還讓加鎖之前的代碼具有可見性;

1.5.面試題

1.5.1.單例模式的七種寫法及單例和并發的關系

? ? ? ? 詳見:單例模式的七種寫法URL

1.5.2.講一講什么是Java內存模型

? ? ? ? 是一組規范,規范了JVM,CPU,JAVA代碼之間一系列轉換關系,Java內存模型最重要是“重排序”,“可見性”,“原子性”這三個部分(重排序講1.3.3.1重排序的例子和重排序的好處),(可見性講因為CPU有多級緩存JMM對內存抽象為“主內存”和“本地內存”,主內存是所有線程所共享的,本地內存是線程獨占的其它線程訪問不了。一個線程對變量的更改是先更新到本地內存中再同步到主內存中,其它線程只能在主內存中同步這個變量的值,因為本地內存同步到主內存是需要時間的這樣就會導致一個線程在本地內存中已經更改了值而這個值還沒有被同步到主內存中去,這樣對于其它線程來說這個值的更改是不可見的,就會導致其它線程重主內存中拿到的值還是一個舊的值,這樣就出現了“線程安全”問題,對于“可見性”來說還有一個happens-before原則即在時間上動作A發生在動作B之前,B保證能看見A的所有操作這就是happens-before;?再可以講下1.3.2.2.4哪些運用了happens-before原則及再講下volatie關鍵字volatile關鍵字),(最后可以再講下1.3.3.3.2Java中的原子操作有哪些);

1.5.3.什么是原子操作?Java中有哪些原子操作?創建對象是原子操作嗎?

? ? ? ? 詳見1.3.33原子性;

1.5.4.64位的double和long寫入的時候是原子的嗎?

? ? ? ? 32位虛擬機上不是原子的,64位虛擬機上是原子的,實際開發中使用的商用Java虛擬機已經處理了這個問題不需要我們再考慮;

1.5.5.volatile和synchronized的異同

? ? ? ? 詳見volatile關鍵字;

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/536749.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/536749.shtml
英文地址,請注明出處:http://en.pswp.cn/news/536749.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Isaac Sim urdf文件導入

本教程展示如何在 Omniverse Isaac Sim 中導入 urdf 一. 使用內置插件導入urdf 安裝urdf 插件 方法是轉到“window”->“Extensions” 搜索框中輸入urdf, 并啟用 通過轉至Isaac Utils -> Workflows -> URDF Importer菜單來訪問 urdf 擴展。 表格中的 1,2,3 對應著…

問題回復:什么是 Java 中的 Lambda 表達式?有什么應用場景?

Lambda 表達式是 Java 8 引入的一項重要特性,它允許在代碼中以更簡潔的方式表達匿名函數(也稱為閉包)。Lambda 表達式的引入是為了提供一種更簡單、更便捷的方式來寫匿名內部類。 Lambda 表達式的語法如下: (parameters) -> …

C語言例題3

1.設x、y、z和k都是int型變量,則執行表達式:x(y4,z16,k32)后,x的值為(32); x(y4,z16,k32),x的值為32 理解逗號運算符在c語言中的工作方式:逗號運算…

Visual Basic的故事

Visual Basic(VB)是一種由Microsoft開發的面向對象的事件驅動編程語言。VB的故事始于上世紀90年代初,它在Windows平臺上的成功對于圖形用戶界面(GUI)應用程序的開發產生了深遠的影響。以下是關于VB發展過程和相關開發者…

VR全景展示的功能有哪些?適合用于哪些領域?

現如今,VR全景展示技術已經逐漸融入了我們的日常生活中,可能大部分人都還沒有意識到VR全景是如何應用的,但其實VR全景針對多個行業的垂直領域都有一定的落地使用。在互聯網高速發展的今天,多媒體所包含的種類也越來越多&#xff0…

【美團大數據面試】大數據面試題附答案

目錄 1.hdfs讀寫流程解析 2.hdfs副本機制,三副本原因,副本存放策略 3.hdfs容錯機制原理 4.MapReduce執行流程詳解 5.spark和mr的區別 6.TopN求法,大數據量無法完全寫入內存解決方案,MapReduce實現方法 7.spark部署、調度原…

SpringAOP復習

SpringAOP AOP為Aspect Oriented Programming的縮寫,意為:面向切面編程。他是一種可以在不修改原來核心代碼的情況俠給程序動態統一進行增強的一種技術 SpringAOP:批量對Spring容器中的bean方法做增強,并且這種增強不會與原來方…

Odoo16 實用功能之在Form視圖的各個部位加入按鈕

目錄 1、 如何在form視圖中的頭部加上按鈕 2、如何在form視圖中的身體加上按鈕 3、如何在notebook標簽中加入按鈕 1、 如何在form視圖中的頭部加上按鈕 以CRM中的渠道form視圖為例子介紹&#xff08;實現紅框中的效果&#xff09; 直接在<header>標簽里加入按鈕即可 …

樹莓派4B搭建開源NAS系統openmediavault

目錄 搭建過程使用鏡像準備硬件準備軟件賬號信息制作系統盤首次啟動配置獲取樹莓派IP地址 ssh登錄到樹莓派上登錄到openmediavualt連接到wifi 搭建過程 搭建過程參考鏈接兩篇文章,已經搭建完畢.期間遇到一些坑,為了方便大家,我把搭建好的鏡像和使用到的工具放在百度網盤共享了…

谷歌Gemini中文疑似套殼百度文心一言

關注盧松松&#xff0c;會經常給你分享一些我的經驗和觀點。 哈哈哈&#xff0c;沒想到谷歌 Gemini 中文語言竟然來自百度的文心一言。 最近知名博主闌夕發微博稱&#xff1a;在 Poe 平臺上對 Gemini-Pro 進行了一個測試。問它 " 你是誰 "&#xff0c;Gemini-Pro 上…

HashSet 和HashMap的區別、優缺點、使用場景

HashSet和HashMap是Java集合框架中的兩個常用類&#xff0c;它們都用于存儲和管理數據&#xff0c;但在使用方式、功能和性能上有很大的區別。 HashSet和HashMap的區別 區別一&#xff1a;用途不同 HashSet&#xff1a;HashSet是一個基于哈希表的集合&#xff0c;用于存儲不…

常用兩種Linux命令生成器

在Linux中&#xff0c;可以使用多種命令來生成隨機密碼。以下是其中兩種常用的命令&#xff1a; 1.pwgen&#xff1a;這個命令可以生成隨機、無意義的但容易發音的密碼。生成的密碼可以只包含小寫字母、大小寫混合或數字。大寫字母和數字會以一種便于記憶的方式放置&#xff0…

Java_Stream流

一、JDK8新特性&#xff08;Stream流&#xff09; 接下來學習一個全新的知識&#xff0c;叫做Stream流&#xff08;也叫Stream API&#xff09;。它是從JDK8以后才有的一個新特性&#xff0c;是專業用于對集合或者數組進行便捷操作的。有多方便呢&#xff1f;我們用一個案例體…

【OAuth2】授權框架的四種授權方式詳解

&#x1f389;&#x1f389;歡迎來到我的CSDN主頁&#xff01;&#x1f389;&#x1f389; &#x1f3c5;我是Java方文山&#xff0c;一個在CSDN分享筆記的博主。&#x1f4da;&#x1f4da; &#x1f31f;推薦給大家我的專欄《OAuth 2》。&#x1f3af;&#x1f3af; &#x1…

go從0到1項目實戰體系二十二:gin構建一個http server

1. 構建一個http server: // api.test.com/topic/main.go: type Topic struct {Id int // 如果寫成小寫的,不能訪問,因為是私有的.Title string } func main() {data : make(map[string]interface{})data["name"] "david"data["age"…

TwIST算法MALTLAB主程序詳解

TwIST算法MALTLAB主程序詳解 關于TwIST算法的具體原理可以參考&#xff1a; 鏈接: https://ieeexplore.ieee.org/abstract/document/4358846 鏈接: https://blog.csdn.net/jbb0523/article/details/52193209 該算法的MATLAB源代碼&#xff1a; 鏈接: http://www.lx.it.pt/~bi…

tcp和udp協議分別是什么意思有什么區別?

TCP&#xff08;傳輸控制協議&#xff09;和UDP&#xff08;用戶數據報協議&#xff09;是兩種網絡傳輸協議&#xff0c;它們在網絡通信中有一些關鍵的區別。 連接性&#xff1a; TCP&#xff1a; 提供面向連接的服務。在通信之前&#xff0c;需要建立連接&#xff0c;數據傳輸…

Node.js(二)-模塊化

1. 模塊化的基本概念 1.1 什么是模塊化 模塊化是指解決一個復雜問題時&#xff0c;自頂向下逐層將系統拆分成若干模塊的過程。對于整個系統來說&#xff0c;模塊是可組合、分解和更換的單元。 1.2 編程領域中的模塊化 編程領域中的模塊化&#xff0c;就是遵守固定的規則&…

48V轉12V 300mA降壓芯片,60V耐壓、0.6A穩壓芯片帶ECO模式-AH590L

AH590L是一種48V轉12V 300mA降壓芯片&#xff0c;具有60V耐壓、0.6A穩壓電流的特點&#xff0c;并且還帶有ECO模式&#xff0c;是一種理想的開關電源解決方案。 AH590L是PWM模式 DC/DC降壓轉換器。TEL&#xff1a;l86*4884*3702*寬輸入電壓范圍4至60V適用于工業領域的廣泛應用…

有意思、好用的免費API分享

Facebook Games Services - Facebook Games Services 為游戲開發者提供了各種服務, 包括(但不限于) 成就 API, 分數 API, 應用通知, 請求, 游戲養成和 Facebook SDK for Unity.Google Play Games Services - Google Developers Games 網站提供了各種 API, SDK 和服務, 包括(但不…