一、堆區java
- 存儲的所有是對象,每一個對象都包含一個與之對應的class的信息。(class的目的是獲得操做指令)
- jvm只有一個heap區,被全部線程共享,不存放基本類型和對象引用,只存放對象自己
堆的優劣勢:數組
- 堆的優點是能夠動態的分配內存大小,生存期也沒必要事先告訴編譯器,java的垃圾收集器會自動收取這些再也不使用的數據
缺點是:數據結構
二、棧區jvm
- 每個線程包含一個stack區,只保存基本數據類型的對象和自定義對象的引用(不是對象),對象都存放在共享heap中
- 每一個棧中的數據(基本數據類型和對象引用)都是私有的,其餘棧不能訪問
棧分爲3部分:線程
- 基本類型變量區
- 執行環境上下文
- 操做指令區(存放操做指令)
棧的優點劣勢:3d
- 存取速度比堆要快,僅次於直接位於CPU的寄存器
- 但必須肯定的是存在stack中的數據大小與生存期必須是肯定的,缺少靈活性
- 單個stack的數據能夠共享
- stack:是一個先進後出的數據結構,一般保存方法中的參數,局部變量
- 在java中,全部基本類型和引用類型都在stack中儲存,棧中數據的生存空間通常在當前scopes內
三、方法區指針
- 又叫靜態區,跟堆同樣,被全部的線程共享。方法區包含全部的class和static變量
- 方法區中包含的都是在程序中永遠的惟一的元素
四、Java中不一樣的存儲數據的地方:對象
寄存器(register)blog
-
最快的存儲區,由於它位於不一樣於其餘存儲區的地方——處理器內部繼承
-
可是寄存器的數量極其有限,因此寄存器由編譯器根據需求進行分配
-
你不能直接控制,也不能在程序中感受到寄存器存在的任何跡象
堆棧(stack)
- 位於通用RAM中,但經過它的「堆棧指針」能夠從處理器哪裏得到支持
- 堆棧指針若向下移動,則分配新的內存;若向上移動,則釋放那些 內存
- 一種快速有效的分配存儲方法,僅次於寄存器
堆(heap)
五、JVM內存模型
大多數JVM將內存分配爲:
- Method Area(方法區)
- Heap(堆)
- Program Counter Register(程序計數器)
- JAVA Method Stack(JAVA方法棧)
- Native Method Stack(本地方法棧)
六、Method Area(方法區)
- 線程共享,存儲已經被虛擬機加載的類信息、常量、靜態變量、即時編譯器編譯後的代碼等等
- HotSpot虛擬機上開發部署人員更願意成爲「永久代」,Permanent Generation
![](http://static.javashuo.com/static/loading.gif)
類型信息
- 類型的全限定名
- 超類的全限定名
- 直接超接口的全限定名
- 類型標誌(該類是類類型仍是接口類型)
- 類的訪問描述符(public、private、default、abstract、final、static)
類型的常量池
- 存放該類型所用到的常量的有序集合
- 包括直接常量(如字符串、整數、浮點數的常量)和對其餘類型、字段、方法的符號引用
- 常量池中每個保存的常量都有一個索引,就像數組中的字段同樣
- 常量池中保存中全部類型使用到的類型、字段、方法的字符引用,因此它也是動態鏈接的主要對象(在動態連接中起到核心做用)
字段信息(該類聲明的全部字段)
- 字段修飾符(public、protect、private、default)
- 字段的類型
- 字段名稱
方法信息(包含類的全部方法,每一個方法包含如下信息)
- 方法修飾符
- 方法返回類型
- 方法名
- 方法參數個數、類型、順序等
- 方法字節碼
- 操做數棧和該方法在棧幀中的局部變量區大小
- 異常表
類變量(靜態變量)
- 該類全部對象共享的變量,即便沒有任何實例對象時,也能夠訪問的類變量。它們與類進行綁定
指向類加載器的引用
- 每個被JVM加載的類型,都保存這個類加載器的引用,類加載器動態連接時會用到
指向Class實例的引用
- 類加載的過程當中,虛擬機會建立該類型的Class實例,方法區中必須保存對該對象的引用
- 經過Class.forName(String className)來查找得到該實例的引用,而後建立該類的對象
方法表
- 爲了提升訪問效率,JVM可能會對每一個裝載的非抽象類,都建立一個數組
- 數組的每一個元素是實例可能調用的方法的直接引用,包括父類中繼承過來的方法
- 這個表在抽象類或者接口中是沒有的
運行時常量池(Runtime Constant Pool)
- Class文件中除了有類的版本、字段、方法、接口等描述信息外
- 還有一項信息是常量池,用於存放編譯器生成的各類字面常量和符號引用
- 這部份內容被類加載後進入方法區的運行時常量池中存放
運行時常量池相對於Class文件常量池的另一個特徵具備動態性
- 能夠在運行期間將新的常量放入池中(典型的如String類的intern()方法)
- 運行時常量池是把Class文件常量池加載進來,每一個類有一個獨立的
- 剛開始時運行的時候常量池裏的連接都是符號連接(只用名字沒有實體),跟在Class文件裏的同樣
- 邊運行邊把常量轉換成直接連接