本篇內容介紹了“java運行時的數據區域分別是什么”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!
Java運行時數據區域
主要用來作為當前線程所執行的字節碼的行號指示器,就是通過它來知道需要執行的字節碼指令地址。這塊區域是線程私有的,你看如果是線程共享的那切換線程之后誰知道下一條執行該執行哪里。如果執行的Native方法的話,計數器的值就不是需要執行的字節碼指令地址了,而是Undefined。
在內存區域中計數器是唯一一個沒有規定OutOfMemoryError情況的區域。
虛擬機棧是線程私有的,也就是每個線程它自身有一個虛擬機棧,棧里面放的是一個一個棧幀,每一個棧幀對應著一個方法的調用,也就是一個方法的調用就是一個棧幀的入棧,方法執行結束就是一個棧幀的出棧。
棧幀主要用來存儲局部變量、操作數棧、動態鏈接、方法出口等信息。所以多線程操作方法內部的局部變量就不需要擔心出什么可見性或者原子性問題了,因為它是線程私有的!
其中的局部變量表存放的是編譯期就已知的各種基本數據類型、對象的引用和returnAddress類型(為字節碼指令jsr、jsr_w和wet服務的,它指向了一條字節碼指令的地址)。
除了long和double占用兩個局部變量空間(slot),其他數據類型都只占用1個空間,其所需的內存空間在編譯器已確定。
當線程請求的棧深度大于虛擬機所允許的深度(例如遞歸深度太深了),將拋出StackOverflowError?;蛘呷绻摂M機棧允許動態擴展那當擴展到無法申請需要的內存時候則拋出OutOfMemoryError。
和虛擬機棧很相似,主要區別就在于它是服務于Native方法,虛擬機棧服務于Java方法。有些虛擬機把本地方法棧和虛擬機棧合二為一例如(HotSpot)虛擬機。并且和虛擬機棧一樣會拋出StackOverflowError和OutOfMemoryError。
絕大部分情況下,堆是這幾部分中所占內存最大的一塊。它是所有線程共享的內存區域,隨著虛擬機的啟動而創建,它的目的就是存放對象實例!所有的對象實例以及數組都要在堆上面分配。
并且堆也是垃圾收集器的主要管理區域。根據垃圾處理器的分代收集算法,在堆中分為新生代和老年代。當內存不足的時候將拋出OutOfMemoryError。
和堆一樣,是所有線程共享的內存區域,用來存放已經被虛擬機加載的類信息、常量、靜態變量、JIT編譯后的代碼等。編譯器時就將各種生成的字面量和符合引用放入常量池,在運行期間也有可能有新的常量加入例如用了String的intern()方法。
根據垃圾處理器的分代收集算法,永久代就在這里。當內存不足的時候將拋出OutOfMemoryError。
直接內存不是虛擬機運行時的數據區域的一部分,但是這里還是來說說。因為它還是很頻繁的被使用的!
NIO(New Input/Output),是通過通道和緩沖區的I/O方式,它使用Native函數庫直接分配堆外內存,然后通過堆中的DirectByteBuffer對象作為引用來操作這塊內存。
正常的內存流應該是本地IO-->直接內存-->非直接內存-->直接內存-->本地IO。
而直接內存就是本地IO-->直接內存-->本地IO。
所以它能在一些通用的場景顯著的提高性能。直接內存的大小受本機的總內存限制!
“java運行時的數據區域分別是什么”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。