方法javaJVM学习笔记-内存处理
本文是一篇關(guān)于方法java的帖子
????大多數(shù)JVM將內(nèi)存區(qū)域分離為Method Area(Non-Heap),Heap,Program Counter Register,Java Method Statck,Native Method Stack和Direct Memomry(備注:Directory Memory并不屬于JVM管理的內(nèi)存區(qū)域)。前三者一般翻譯為:方法區(qū)、堆、程序計(jì)數(shù)器。但不同的資料和書籍對(duì)于后者的翻譯名不盡相同,這里將他們分離翻譯為:Java方法棧、本地方法棧和直接內(nèi)存區(qū)域。對(duì)于不同的JVM。內(nèi)存區(qū)域分離可能會(huì)有所差異,比如Hot Spot就將Java方法棧和本地方法棧合二為一,統(tǒng)稱為方法棧(Method Stack)
????首先我們熟悉一下一個(gè)一般的Java程序的任務(wù)過(guò)程。一個(gè)Java源文件,會(huì)被編譯成字節(jié)碼(ByteCode),然后告訴JVM程序的運(yùn)行入口,在被JVM通過(guò)字節(jié)碼解釋器加載運(yùn)行。那么程序開始運(yùn)行后,是如何涉及到各內(nèi)存區(qū)域的呢?
????概括地說(shuō),JVM每碰到一個(gè)線程,就為其分配一個(gè)程序計(jì)數(shù)器、Java方法棧和本地方法棧。當(dāng)線程終止時(shí),兩者所占有的內(nèi)存空間會(huì)被釋放掉。棧中保存的是棧幀,可以說(shuō)每個(gè)棧幀對(duì)應(yīng)一個(gè)“運(yùn)行現(xiàn)場(chǎng)”。如果出現(xiàn)一個(gè)局部對(duì)象,則它的實(shí)例數(shù)據(jù)被保存在堆中,而類數(shù)據(jù)被保存在方法區(qū)。
????我們用下面這一段文字就描述完了每個(gè)內(nèi)存區(qū)域的基本功能,但是這還是比擬粗拙,下面就分離分析它們的存儲(chǔ)對(duì)象、生存周期與空間管理策略。
????程序計(jì)數(shù)器
????
- 線程特性:私有
- 存儲(chǔ)內(nèi)容:字節(jié)碼文件指令地址(Java Methods),或Undefined(Native Methods)
- 生命周期:隨線程而生逝世
- 空間策略:占用內(nèi)存很小
????這個(gè)最簡(jiǎn)略,就先從它提及。程序計(jì)數(shù)器,是線程私有(與線程共享相對(duì))的,也就是說(shuō)有N個(gè)線程,JVM就會(huì)分配N個(gè)程序計(jì)數(shù)器。如果當(dāng)線程在執(zhí)行一個(gè)Java方法,程序計(jì)數(shù)器記錄這著線程所執(zhí)行的字節(jié)碼文件中的指令地址。線程執(zhí)行的是一個(gè)Native方法,則計(jì)數(shù)器值為Undefined。
????程序計(jì)數(shù)器測(cè)生存周期多長(zhǎng)呢?明顯程序計(jì)數(shù)器是伴隨著線程而生,伴隨線程逝世而逝世的,并且程序計(jì)數(shù)器占用的內(nèi)存空間也很小。
????Java方法發(fā)棧與本地方法棧
????Java方法棧也是線程私有的,每個(gè)Java方法棧都是由一個(gè)個(gè)棧幀組成的,每個(gè)棧幀是一個(gè)方法運(yùn)行期的基礎(chǔ)數(shù)據(jù)結(jié)構(gòu),它存儲(chǔ)局部變量表,操作數(shù)棧、動(dòng)態(tài)鏈表、方法出口等信息。當(dāng)線程調(diào)用了一個(gè)Java方法時(shí),一個(gè)棧幀就被壓入(Push)到響應(yīng)的Java方法棧。當(dāng)線程從一個(gè)Java方法返回時(shí),響應(yīng)的Java方法棧就彈出(Pop)一個(gè)棧幀。
????其中要具體分析的是局部變量表,它保存著各種基本數(shù)據(jù)類型和對(duì)象引用(Object reference)。基本數(shù)據(jù)類型包括boolean、byte、char、short、int、long、float、double。對(duì)象引用,本質(zhì)就逝世一個(gè)地址(也可以說(shuō)是一個(gè)“指針”),該地址是堆中的一個(gè)地址,通過(guò)這個(gè)地址可以找到響應(yīng)的Object(注意“找到”,具體原因會(huì)在下面解釋)。而這個(gè)地址找到響應(yīng)Object的方式有兩種。一種是該地址存儲(chǔ)著Pointer to Object Instance Data和Pointer to Object Class Data;另一種是該地址存儲(chǔ)著Object Instance Data,其中又包含有Pointer to Object Class Data。
????
????圖1:間接方式
????
每日一道理我拽著春姑娘的衣裙,春姑娘把我?guī)У搅司G色的世界里。
????
????圖2:直接方式
????
????第一種方式,Java方法棧中有Handler Pool和Instance Pool,無(wú)倫哪種方式,Object Class Data都是存儲(chǔ)在方法區(qū)的,Object Instance Data都是存儲(chǔ)在堆中的。
????原生方法棧和Java方法棧相類似,這里不再贅述。
????堆
????堆是在啟動(dòng)虛擬機(jī)的時(shí)候分離出來(lái)的區(qū)域,其大小由參數(shù)或者默許參數(shù)指定。當(dāng)虛擬機(jī)終止運(yùn)行時(shí),會(huì)釋放堆內(nèi)存 。一個(gè)JVM只有一個(gè)堆,它自然是線程共享的。堆中存儲(chǔ)的是所有的Object Instant Data以及數(shù)組(不過(guò)隨著棧上分配技術(shù)、標(biāo)量替換技術(shù)等優(yōu)化手段的開展,對(duì)象也紛歧建都存儲(chǔ)在堆上了),這些Instance由渣滓管理器(GrabageCollector)管理,具體會(huì)在后面的章節(jié)闡述。
????堆可所以由不連續(xù)的物理內(nèi)存空間組成的,并且既可以固定大小,也可以設(shè)置為可擴(kuò)展的(Scalable)。
????方法區(qū)
????通過(guò)上述Java方法棧的分析,大家已經(jīng)知道Object Class Data是存儲(chǔ)在方法區(qū)的。除此以外,常量、靜態(tài)變量、JIT編譯后的代碼也都都是在方法區(qū)。正因?yàn)榉椒ㄈゴ鎯?chǔ)的數(shù)據(jù)與堆有一種類比關(guān)系,所以還被稱為Non-Heap。方法區(qū)也可所以內(nèi)存不連續(xù)的區(qū)域組成的,并且可設(shè)置為固定大小,也可以設(shè)置稱為可擴(kuò)展的,這點(diǎn)與堆一樣。
????方法區(qū)外部有一個(gè)非常重要的區(qū)域,叫做運(yùn)行時(shí)常量池(Runtime Constant Pool,簡(jiǎn)稱RCP)。在字節(jié)碼文件中常量池(Constant Pool Table),用于存儲(chǔ)編譯器產(chǎn)生的字面量和符號(hào)引用。每個(gè)字節(jié)碼文件中的常量池在類被加載后,都市存儲(chǔ)到方法區(qū)中。值得注意的是,運(yùn)行是產(chǎn)生的新常量也可以被放入常量吃中,比如String類中的intern()方法產(chǎn)生的常量。
????直接內(nèi)存區(qū)
????直接內(nèi)存區(qū)并不是JVM管理的內(nèi)存區(qū)域的一部分,而是其以外。該區(qū)域也會(huì)在Java開發(fā)中使用到,并且存在致使內(nèi)存溢出的隱患。如果對(duì)NIO有所懂得,應(yīng)該會(huì)知道NIO是可以使用Native Methods來(lái)使用直接內(nèi)存區(qū)的。
????
文章結(jié)束給大家分享下程序員的一些笑話語(yǔ)錄: 《諾基亞投資手機(jī)瀏覽器UCWEB,資金不詳或控股》杯具了,好不容易養(yǎng)大的閨女嫁外國(guó)。(心疼是你養(yǎng)的嗎?中國(guó)創(chuàng)業(yè)型公司創(chuàng)業(yè)初期哪個(gè)從國(guó)有銀行貸到過(guò)錢?)
--------------------------------- 原創(chuàng)文章 By
方法和java
---------------------------------
轉(zhuǎn)載于:https://www.cnblogs.com/xinyuyuanm/p/3150273.html
總結(jié)
以上是生活随笔為你收集整理的方法javaJVM学习笔记-内存处理的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 全车18喇叭化身移动KTV 哈弗酷狗上市
- 下一篇: oracle insert两个关联表