JVM各内存区域存放内容
一、方法區存放內容:
1.類的全限定名(類的全路徑名)。
2.類的直接超類的權全限定名(如果這個類是Object,則它沒有超類)。
3.類的類型(類或接口)。
4.類的訪問修飾符,public,abstract,final等。
5.類的直接接口全限定名的有序列表。
6.常量池(字段,方法信息,靜態變量,類型引用(class))等
當jvm使用類裝載器裝在某個類時,它首先要定位到對應的class文件,然后讀入這個class文件,最后提取該文件的內容信息,并將這些信息存儲到方法區,最后返回一個class實例。
方法區是系統分配的一個內存邏輯區域,是一塊所有線程共享的內存區域,用來存儲類型信息(類型信息可以理解為類的描述信息(類的全限定名,訪問修飾符,字段,方法等)),方法區的大小決定了系統可以包含多少個類,如果系統類太多,方法區內存不夠會導致方法區溢出,虛擬機同樣會拋出內存溢出信息。方法去特點:
1.方法區是線程安全的,由于所有的線程都共享方法區,所以方法區里的數據訪問必須被設計成線程安全的。例如,假如同時有兩個線程都企圖訪問方法區中的同一個類,而這個類還沒有被裝入jvm,那么只允許一個線程去裝在它,而其他線程必須等待。
2.方法去的大小不必是固定的,jvm可根據應用需要動態調整,同時,方法區也不一定是連續的,方法區可以在一個堆(甚至是jvm自己的堆)中自由分配。
3.方法區也可被垃圾收集,當某個類不在被使用時,jvm將卸載這個類,進行垃圾收集。
?
String str=new String("hello");
堆 存放的是new出來的對象? jvm中只有一個堆區 被所有的線程共享
棧 是變量str? 每個棧中的數據私有的 其他棧不能訪問。
方法區 是“hello”;被所有的線程共享,方法區包含所有的class static變量。
?
程序計數器:
一、先來看看概念
多線程的Java應用程序:為了讓每個線程正常工作就提出了程序計數器(Programe Counter Register),每個線程都有自己的程序計數器這樣當線程執行切換的時候就可以在上次執行的基礎上繼續執行,僅僅從一條線程線性執行的角度而言,代碼是一條一條的往下執行的,這個時候就是程序計數器;JVM就是通過讀取程序計數器的值來決定下一條需要執行的字節碼指令,進而進行選擇語句、循環、異常處理等;
這個還沒看懂的話不要緊,繼續往下走咯。
二、簡單粗暴的舉例
1.生活中的案例
比如老王正在看電影,他看到三十五分鐘的時候,突然他的QQ好友給他開視頻聊天,這時候肯定打斷他看電影了,假設他qq好友和他視頻完了,他肯定要接著他那35分鐘的進度去繼續看,這時候他怎么知道我看到35分鐘了?這時候程序計數器就起了作用,他負責管理進度。
是不是略微懂了一點呢?
2.代碼層面的案例
將上面的例子轉換成代碼,是這樣的:
A線程正在執行HelloWorld.class的第三十五行。這時候CPU時間片被B線程搶走了,當A線程重新被分配到時間片時,他怎么知道我的class運行到哪了?這時候他可以看程序計數器在哪個位置。
這下總該明白了吧?
三、JVM程序計數器的總結
程序計數器作用不多說了,我個人感覺他是為了多線程而生的,單線程情況下完全不需要他。從案例中不難發現,程序計數器是每個線程獨有的,并非線程共享的,所以是線程安全的!
?
本地方法棧:
對于一個運行中的Java程序而言,它還可能會用到一些跟本地方法相關的數據區。當某個線程調用一個本地方法時,它就進入了一個全新的并且不再受虛擬機限制的世界。本地方法可以通過本地方法接口來訪問虛擬機的運行時數據區,但不止如此,它還可以做任何它想做的事情。
本地方法本質上時依賴于實現的,虛擬機實現的設計者們可以自由地決定使用怎樣的機制來讓Java程序調用本地方法。
任何本地方法接口都會使用某種本地方法棧。當線程調用Java方法時,虛擬機會創建一個新的棧幀并壓入Java棧。然而當它調用的是本地方法時,虛擬機會保持Java棧不變,不再在線程的Java棧中壓入新的幀,虛擬機只是簡單地動態連接并直接調用指定的本地方法。
如果某個虛擬機實現的本地方法接口是使用C連接模型的話,那么它的本地方法棧就是C棧。當C程序調用一個C函數時,其棧操作都是確定的。傳遞給該函數的參數以某個確定的順序壓入棧,它的返回值也以確定的方式傳回調用者。同樣,這就是虛擬機實現中本地方法棧的行為。
很可能本地方法接口需要回調Java虛擬機中的Java方法,在這種情況下,該線程會保存本地方法棧的狀態并進入到另一個Java棧。
下圖描繪了這樣一個情景,就是當一個線程調用一個本地方法時,本地方法又回調虛擬機中的另一個Java方法。
這幅圖展示了JAVA虛擬機內部線程運行的全景圖。一個線程可能在整個生命周期中都執行Java方法,操作它的Java棧;或者它可能毫無障礙地在Java棧和本地方法棧之間跳轉。
該線程首先調用了兩個Java方法,而第二個Java方法又調用了一個本地方法,這樣導致虛擬機使用了一個本地方法棧。假設這是一個C語言棧,其間有兩個C函數,第一個C函數被第二個Java方法當做本地方法調用,而這個C函數又調用了第二個C函數。之后第二個C函數又通過本地方法接口回調了一個Java方法(第三個Java方法),最終這個Java方法又調用了一個Java方法(它成為圖中的當前方法)。
?
?
總結
以上是生活随笔為你收集整理的JVM各内存区域存放内容的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: iOS UITableview 禁止上下
- 下一篇: 比尔盖茨的风流情史,妻子同意他与前女友同