摘要:抽時(shí)間重新讀了一遍深入理解一書。驗(yàn)證確保文件的字節(jié)流中包含的信息符合當(dāng)前虛擬機(jī)的要求,并且不會(huì)危害虛擬機(jī)自身的安全??梢娦钥梢娦允侵府?dāng)一個(gè)線程修改了共享變量的值,其他線程能夠立即得知這個(gè)修改。
抽時(shí)間重新讀了一遍《深入理解JVM》一書。以下為摘錄內(nèi)容。
1 java內(nèi)存區(qū)域java虛擬機(jī)運(yùn)行時(shí)數(shù)據(jù)區(qū)
1.1 程序計(jì)數(shù)器是一塊較小的內(nèi)存空間,可以看做是當(dāng)前線程所執(zhí)行的字節(jié)碼的行號(hào)指示器。每條線程都有一個(gè)獨(dú)立的程序計(jì)數(shù)器,各條線程之間計(jì)數(shù)器互不影響。
1.2 java虛擬機(jī)棧描述的是java方法執(zhí)行的內(nèi)存模型:每個(gè)方法在執(zhí)行的同時(shí)都會(huì)創(chuàng)建一個(gè)棧幀用于存儲(chǔ)局部變量表、操作數(shù)棧、動(dòng)態(tài)鏈接、方法出口等信息。
局部變量表存放了編譯器可知的各種基本數(shù)據(jù)類型、對(duì)象引用和returnAddress類型。
1.3 本地方法棧虛擬機(jī)棧為虛擬機(jī)執(zhí)行java方法服務(wù),二本地方法棧為虛擬機(jī)使用到的Native方法服務(wù)。
1.4 java堆被所有線程共享的一塊內(nèi)存區(qū)域,在虛擬機(jī)啟動(dòng)時(shí)創(chuàng)建。java堆是垃圾收集器管理的主要區(qū)域,因此很多時(shí)候也被叫做GC堆。
1.5 方法區(qū)各個(gè)線程共享的內(nèi)存區(qū)域,用于存儲(chǔ)已被虛擬機(jī)加載的類信息、常量、靜態(tài)變量、即時(shí)編譯器編譯后的代碼等數(shù)據(jù)。
1.6 運(yùn)行時(shí)常量池方法區(qū)的一部分。需要注意的是string的intern方法在jdk1.6前后的不同。jdk1.6之后常量池放到了堆中。
1.7 直接內(nèi)存并不是虛擬機(jī)運(yùn)行時(shí)數(shù)據(jù)區(qū)的一部分,也不是java虛擬機(jī)規(guī)范中國(guó)定義的內(nèi)存區(qū)域。NIO引入的通道和緩沖區(qū)可以使用native函數(shù)庫(kù)直接分配對(duì)外內(nèi)存。
2 垃圾收集器與內(nèi)存分配策略 2.1 判斷對(duì)象是否存活的算法:引用計(jì)數(shù)算法:很難解決對(duì)象之間相互循環(huán)引用的問題
可達(dá)性分析算法:通過一系列GC Roots的對(duì)象作為起始點(diǎn),從這些節(jié)點(diǎn)開始向下搜索,搜索所走過的路線稱為引用鏈,當(dāng)一個(gè)對(duì)象到GC Roots沒有任何引用鏈相連時(shí),則證明此對(duì)象是不可用的。
2.2 垃圾收集算法標(biāo)記-清除算法:效率低,空間碎片化
復(fù)制算法:運(yùn)行簡(jiǎn)單高效,代價(jià)高,降低了一半的使用率
標(biāo)記-整理算法
分代收集:新生代用復(fù)制算法,老年代用標(biāo)記整理算法
3 虛擬機(jī)類加載機(jī)制加載、驗(yàn)證、準(zhǔn)備、解析、初始化。
3.1 有且只有5種情況必須立即對(duì)類進(jìn)行初始化1)遇到new、getstatic、putstatic或invokestatic這4條指令字節(jié)碼時(shí),如果類沒有進(jìn)行過初始化,則需要先觸發(fā)其初始化。
2)使用java.lang.reflect包的方法對(duì)類進(jìn)行反射調(diào)用的時(shí)候,如果類沒有進(jìn)行過初始化,則需要先觸發(fā)其初始化。
3)當(dāng)初始化一個(gè)類的時(shí)候,如果發(fā)現(xiàn)其父類還沒有進(jìn)行過初始化,需要先觸發(fā)其父類的初始化。
4)當(dāng)虛擬機(jī)啟動(dòng)時(shí),需要制定main,虛擬機(jī)會(huì)先初始化main類。
5)當(dāng)使用jdk1.7的動(dòng)態(tài)語言支持時(shí),如果java.lang.invoke.MethodHandle實(shí)例最后的解析結(jié)果REF_getStatic、REF_putStatic、REF_invokeStatic的方法句柄,并且這個(gè)方法句柄所對(duì)應(yīng)的類沒有進(jìn)行過初始化,則需要先觸發(fā)其初始化。
3.2 類加載的過程 3.2.1 加載1)通過一個(gè)類的全限定名來獲取定義此類的二進(jìn)制字節(jié)流
2)將這個(gè)字節(jié)流所代表的靜態(tài)存儲(chǔ)結(jié)構(gòu)轉(zhuǎn)換為方法區(qū)的運(yùn)行時(shí)數(shù)據(jù)結(jié)構(gòu)
3)在內(nèi)存中生成一個(gè)代表這個(gè)類的java.lang.Class對(duì)象,作為方法區(qū)這個(gè)類的各種數(shù)據(jù)的訪問入口。
3.2.2 驗(yàn)證確保Class文件的字節(jié)流中包含的信息符合當(dāng)前虛擬機(jī)的要求,并且不會(huì)危害虛擬機(jī)自身的安全。
文件格式驗(yàn)證——元數(shù)據(jù)驗(yàn)證——字節(jié)碼驗(yàn)證——符號(hào)引用驗(yàn)證
3.2.3 準(zhǔn)備正式為類變量分配內(nèi)存并設(shè)置類變量初始值的階段,這些變量所使用的內(nèi)存都將在方法區(qū)中進(jìn)行分配。這時(shí)候進(jìn)行內(nèi)存分配的僅包括類變量(被static修飾的變量),二不包括實(shí)例變量。
3.2.4 解析解析階段是虛擬機(jī)將常量池內(nèi)的符號(hào)引用替換為直接引用的過程。
類和接口的解析、字段解析、類方法解析、接口方法解析
3.2.5 初始化類初始化階段是類加載過程的最后一步。在準(zhǔn)備階段,變量已經(jīng)賦過一次系統(tǒng)要求的初始值,而在初始化階段,則根據(jù)程序員通過程序指定的主觀計(jì)劃去初始化類變量和其他資源,或者可以從另一個(gè)角度來表達(dá):初始化階段是執(zhí)行類構(gòu)造器
硬件的效率與一致性
java內(nèi)存模型(JMM)
線程、主內(nèi)存、工作內(nèi)存之間的交互關(guān)系
java內(nèi)存模型規(guī)定了所有的變量都存儲(chǔ)在主內(nèi)存中,每條線程有自己的工作內(nèi)存,線程的工作內(nèi)存中保存了被該線程使用到的變量的主內(nèi)存副本拷貝,線程對(duì)變量的所有操作(讀取、賦值)都必須在工作內(nèi)存中進(jìn)行,而不能直接讀寫主內(nèi)存中的變量。線程間變量值的傳遞均需要通過主內(nèi)存來完成。
java內(nèi)存模型時(shí)圍繞著在并發(fā)過程中如何處理原子性、可見性和有序性這三個(gè)特征來建立的。
原子性:通過read、load、assign、user、store、write操作來保證。通過lock和unlock也可以滿足。
可見性:可見性是指當(dāng)一個(gè)線程修改了共享變量的值,其他線程能夠立即得知這個(gè)修改。Java內(nèi)存模型是通過在變量修改后將新值同步回主內(nèi)存,在變量讀取前從主內(nèi)存刷新變量值這種依賴主內(nèi)存作為傳遞媒介的方式來實(shí)現(xiàn)可見性的,無論普通變量還是volatile變量都是如此,普通變量與volatile變量的區(qū)別是,volatile的特殊規(guī)則保證了新值能夠立即同步到主內(nèi)存,以及每次使用前立即從主內(nèi)存刷新。volatile保證了多線程操作時(shí)變量的可見性,二普通變量不能保證這一點(diǎn)。(synchronized和final關(guān)鍵字)
有序性:volatile和synchronized保證線程之間操作的有序性,volatile本身就包含了禁止指令重排序的語義。
先行發(fā)生原則 保證了我們大多數(shù)情況下不用關(guān)心太多。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/73343.html
摘要:年開始工作,年畢業(yè),兩年來的工作接觸知識(shí)面很廣,用的東西比較多,包括基礎(chǔ)的開發(fā)到開發(fā)到大數(shù)據(jù),推薦系統(tǒng),到服務(wù)器運(yùn)維,到數(shù)據(jù)庫(kù)維護(hù),,,可愈發(fā)明白貪多嚼不爛的道理,唯有才能踏踏實(shí)實(shí),趁著剛剛讀完這本書,想復(fù)習(xí),順便寫一些筆記,聊以鞏固。 13年開始工作,14年畢業(yè),兩年來的工作接觸知識(shí)面很廣,用的東西比較多,包括基礎(chǔ)的java開發(fā)到j(luò)2ee,web開發(fā),到大數(shù)據(jù),推薦系統(tǒng),到服務(wù)器運(yùn)維...
摘要:開頭正式開啟我入職的里程,現(xiàn)在已是工作了一個(gè)星期了,這個(gè)星期算是我入職的過渡期,算是知道了學(xué)校生活和工作的差距了,總之,盡快習(xí)慣這種生活吧。當(dāng)時(shí)是看的廖雪峰的博客自己也用做爬蟲寫過幾篇博客,不過有些是在前人的基礎(chǔ)上寫的。 showImg(https://segmentfault.com/img/remote/1460000010867984); 開頭 2017.08.21 正式開啟我...
摘要:探索專為而設(shè)計(jì)的將探討進(jìn)行了何種改進(jìn),以及這些改進(jìn)背后的原因。關(guān)于最友好的文章進(jìn)階前言之前就寫過一篇關(guān)于最友好的文章反響很不錯(cuò),由于那篇文章的定位就是簡(jiǎn)單友好,因此盡可能的摒棄復(fù)雜的概念,只抓住關(guān)鍵的東西來講,以保證大家都能看懂。 周月切換日歷 一個(gè)可以進(jìn)行周月切換的日歷,左右滑動(dòng)的切換月份,上下滑動(dòng)可以進(jìn)行周,月不同的視圖切換,可以進(jìn)行事件的標(biāo)記,以及節(jié)假日的顯示,功能豐富 Andr...
摘要:的重要性毋庸置疑,可以毫不夸張的說虛擬機(jī)是整個(gè)平臺(tái)的基石。方面的知識(shí),也一直是等大廠面試考核的重點(diǎn)。本專欄將分為如下幾個(gè)大模塊進(jìn)行分析開篇介紹運(yùn)行時(shí)數(shù)據(jù)區(qū)。最主要的是讓我知道能得到多少小伙伴的認(rèn)可,畢竟大家的認(rèn)可,就是不懈努力的動(dòng)力 JVM的重要性毋庸置疑,可以毫不夸張的說Java虛擬機(jī)是整個(gè)Java平臺(tái)的基石。 JVM方面的知識(shí),也一直是BAT等大廠面試考核的重點(diǎn)。特別是JVM調(diào)優(yōu),...
摘要:但是為了豐富引用的種類,以適應(yīng)各種應(yīng)用,中加入了中引用,但是除了強(qiáng)引用,其生命周期會(huì)有所不同,生存能力遞減。加載該類的已被回收。 GC面臨的問題有三個(gè):哪些內(nèi)存需要回收、什么時(shí)候回收和怎么回收 哪些內(nèi)存需要回收,一般有兩種方法 引用計(jì)數(shù) 對(duì)每個(gè)對(duì)象都有個(gè)被引用的次數(shù),單被引用的次數(shù)為0的時(shí)候,就表示對(duì)象需要被回收 引用計(jì)數(shù)的缺點(diǎn)是沒有辦法解決循環(huán)引用導(dǎo)致的內(nèi)存泄露問題 ...
閱讀 2782·2021-10-26 09:50
閱讀 2424·2021-10-11 11:08
閱讀 2165·2019-08-30 15:53
閱讀 1929·2019-08-30 15:44
閱讀 2413·2019-08-28 18:12
閱讀 2558·2019-08-26 13:59
閱讀 2881·2019-08-26 12:19
閱讀 2789·2019-08-26 12:09