jAVA內存區域劃分


http://bbs.itheima.com/thread-51574-1-1.html

在C/C++開發中,自己需要進行內存管理,而java由於JVM的自動內存管理機制的幫助,不在需要爲每一個new操作寫配對的delete和free代碼了,但由於內存泄露和益出方面的問題,在這小結下java內存區域中的一些知識。

    java虛擬機運行時數據區如下:

主要包括五個部分:程序計數器、java虛擬機棧、本地方法棧、java堆、方法區(運行時常量池)。
(1)程序計數器(線程私有):
    程序計數器是一塊較小的內存空間,它的作用可以看做事當前線程所執行的字節碼的行號指示器。如執行字節碼指令、分支、循環、跳轉、異常處理、線程恢復等基礎功能。
   JVM一次能支持很多線程執行。每一個JVM線程有它自己的程序計數器。在任何時候,一個JVM的線程都正在執行當前線程的方法代碼。如果這個方法是一個java方法,程序計數器記錄的是正在執行的虛擬機字節碼指令的地址。如果線程正在執行本地方法,程序計數器的值爲未定義。JVM程序計數器足以存儲一個返回地址或一個本地指針。

(2)java虛擬機棧(線程私有):
    每個JVM的線程在創建的時候,都會創建一個棧。一個棧包含很多棧楨。棧幀用來存儲局部變量表(存放了編譯器的各種基本數據類型如boolean、byte、char、short、int、float、long、double;對象引用(不同虛擬機存儲的不同如指向對象起始地址的引用指針或者是代表對象的句柄);returnaddress類型)、操作棧、動態鏈接、方法出口等信息。
  在java虛擬機規範中,對這個區域規定了兩種異常狀況:
      a。如果線程請求的棧深度大於虛擬機所允許的深度,將拋出StackOverflowError異常。
      b.如果VM棧可以動態擴展,當擴展時無法申請到足夠內存(或者在初始化新線程時沒有足夠內存在創建棧)則拋出OutOfMemoryError異常。

(3) 本地方法棧:
    本地方法棧和java虛擬機棧的作用類似。只是java虛擬機棧爲執行java方法(也就是字節碼)服務,本地方法棧則爲虛擬機使用到的native方法服務。
  在java虛擬機規範中,對這個區域規定了兩種異常狀況:
      a。如果線程請求的棧深度大於虛擬機所允許的深度,將拋出StackOverflowError異常。
      b.如果VM棧可以動態擴展,當擴展時無法申請到足夠內存(或者在初始化新線程時沒有足夠內存在創建棧)則拋出OutOfMemoryError異常。

(4)java堆
       JVM有一個在所有線程內共享的堆。堆是給所有類的實例和數組分配內存的運行時數據區。 堆在虛擬機啓動的時候創建,堆中儲存的對象通過一個自動存儲管理系統(垃圾回收器)進行回收。 對象從不明確的被分配(JVM從不指明對象的釋放)。JVM加上沒有(JVM不指定特定的自動存儲管理系統)自動存儲管理系統的特別的類型,(開發者可根據系統要求自主選擇)並且這個存儲管理技術可能被選擇按照實現的系統需求。
    java堆是垃圾收集器管理的主要區域,也被稱爲“GC堆”。
      堆要麼是固定大小,要麼按計算需要擴展。如果一個大的堆變得多餘或許會收縮。堆的內存不需要相鄰。使用者可以設置堆內存的大小,如果堆能夠動態的擴展。控制最大最小堆內存。
堆會出現以下異常:
    如果內存溢出(若計算所需堆內存不足),則拋出OutOfMemoryError 

(5)方法區
      JVM的方法區是所有線程共享的,方法區類似於傳統語言編譯代碼時的存儲區域或類似於操作系統進程的文本段。他存儲內容包括:每一個類的結構,如運行時常量池,字段和方法的數據;方法和構造器的代碼,如用於類,實例和接口初始化的特殊方法。這個方法區在JVM啓動的時候被創建,一般情況下JVM不會選擇對方法區進行垃圾回收或者壓縮,這個版本的JVM規範沒有強制規定方法區的位置和管理編譯後代碼的策略。方法區可固定大小,或按需伸縮。方法區的內存不需要相鄰。
   運行時常量池(方法區的一部分):
      運行時常量池是類和接口運行時的常量池表,它在字節碼文件裏。它包含幾類常量。 在編譯時期識別的數值常量,在運行區識別的方法或引用字段。運行區常量池類似於傳統語言的字符表,但它比傳統字符表所存儲的範圍更廣。每一個運行區常量池從方法區分配內存。當類和接口被JVM創建時相應的常量池也被創建。
       運行區常量池包括以下異常:
  當類和接口創建時,如果運行區常量池所需內存不足,則拋出OutOfMemoryError。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章