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