java語言中不需要像C/C++語言那樣需要自己管理內存,內存的申請與釋放全部由JVM進行統一管理,這樣java中只一個new
關鍵字就可以申請內存了。但不是說不用自己管理內存就代表內存不會出現內存泄露了,如果長時間持有對象而不釋放很容易造成內存泄露。
通過上圖可以知道java運行時數據區域劃分為五個部分:
1.方法區
2.堆
3.虛擬機棧
4.本地方法棧
5.程序計數器
方法區 (Method Area)
方法區用于存儲已被虛擬機加載的類信息、常量、靜態變量、即時編譯器編譯后的代碼等數據。
運行時常量池:方法區的一部分。Class文件中除了有類的版本、字段、方法、接口等描述信息外,還有一項信息是常量池,用于存放編譯期生成的各種字面量和符號引用,這部分內容將在類加載后進入方法區的運行時常量池中存放。
堆 (Java Heap)
對于大多數應用來說,Java堆是Java虛擬機所管理的內存中最大的一塊。Java堆是被所有線程共享的一塊內存區域,在虛擬機啟動時創建。該區域的唯一目的就是存放對象實例,幾乎所有的對象實例都在這里分配內存。該區域也是垃圾收集器的主要區域。
虛擬機棧 (Java Virtual Machine Stacks)
線程私有,生命周期與線程相同。虛擬機棧描述的是Java方法執行的內存模型:每個方法在執行的同時會創建一個棧幀(Stack Frame)用于存儲局部變量表、操縱數棧、動態鏈接、方法出口等信息。每一個方法從調用直至執行完成的過程,就對應一個棧幀在虛擬機中入棧到出棧的過程。
局部變量表:存放了編譯器可知的各種基本數據類型,對象引用和returnAddress。
本地方法棧 (Native Method Stack)
與虛擬機棧的作用相似,兩者的區別虛擬機棧為虛擬機執行Java方法服務,而本地方法棧為虛擬機用到的Native方法服務。
程序計數器 (Program Counter Register)
一塊較小的內存區域,可以看作是當前線程所執行的字節碼的行號指示器。在虛擬機的概念模型里,字節碼解釋器工作時就是通過改變這個計數器的值來選取下一條需要執行的字節碼指令,分支、循環、跳轉、異常處理、線程回復等基礎功能都需要依賴這個計數器來完成。
每條線程都需要有一個獨立的程序計數器,各個線程之間計數器互不影響,獨立存儲。