Java中的內存劃分

Java程序在運行時,需要在內存中分配空間。爲了提高效率,就對數據進行了不同空間的劃分,因爲每一片區域都有特定的處理數據方式和內存管理方式。
      程序計數器:保證線程切換後能恢復到原來的執行位置
      虛擬機棧:(棧內存)爲虛擬機執行java方法服務:方法被調用時創建棧幀->局部變量表->局部變量、對象引用
      本地方法棧:爲虛擬機執行使用到的native方法服務
      堆內存:存放所有new出來的東西
      方法區:存儲被虛擬機加載的類信息、常量、靜態常量、靜態方法等。

GC對它們的回收:
    內存取餘中的程序計數器、虛擬機棧、本地方法棧這3個取餘隨着線程而生,線程而滅;棧中的棧幀隨着方法的進入和退出而有條不紊地執行者出棧和入棧的操作,每個棧幀中分配多少內存基本是在類結構確定下來時就一直的。在這幾個區域不需要過多考慮回收的問題,因爲方法結束或者線程結束時,內存自然跟着回收了。

GC回收的主要對象:
   1.程序計數器(線程私有)
     每個線程擁有一個程序計數器,在線程創建時創建,指向下一條指令的地址,執行本地方法時,其值爲undefined
爲了線程切換後能夠恢復到正確的執行位置,每條線程都有一個獨立的程序計數器。
   2.java虛擬機棧(線程私有)
     每個方法被調用時都會創建一個棧幀,用於存儲局部變量表、操作站、動態鏈接、方法出口等信息。局部變量表存放的是:編譯器剋制的基本數據類型、對象引用類型。
    每個方法被調用到執行完成的過程,就對應着一個棧幀在虛擬機中從入棧到出棧的過程。
     在Java虛擬機規範中,對這個區域規定了兩種異常情況:
    (1)如果線程請求的棧深度太深,超出了虛擬機所允許的深度,就會出現stackOverFlowError(比如無限遞歸。因爲每一層棧幀都佔用一定空間,而Xss規定了棧的最大空間,超出這個值就會報錯)
    (2)虛擬機棧可以動態擴展,如果擴展到無法申請足夠的內存空間,會出現OOM
   3.本地方法棧
     (1)本地方法棧與java虛擬機棧作用非常相似,奇缺別是:java虛擬機棧是爲虛擬機執行java方法服務的,而本地方法棧則爲虛擬機使用到的Native方法服務
   4.java堆:即堆內存(線程共享)
     (1)堆是java虛擬機所管理的內存區域中的最大的一塊,java堆是被所有線程共享的內存區域,在java虛擬機啓動時創建,堆內存的唯一目的就是存放對象實例幾乎所有的對象實例都在堆內存分配。
     (2)堆是GC管理的主要區域 從垃圾回收的角度, 由於現在的垃圾收集器都是採用的分代收集算法,因此java堆還可以初步細分爲新生代和老年代。 
    (3)Java虛擬機規定,堆可以處於物理上不連續的內存空間中,只要邏輯上連續的即可。在實現上既可以是固定的,也可以是可動態擴展的。如果在堆內存沒有完成實例分配,並且堆大小也無法擴展,就會拋出OutOfMemoryError異常。

     5、方法區:(線程共享) 
    (1)用於存儲已被虛擬機加載的類信息、常量、靜態變量、即時編譯器編譯後的代碼等數據。 
     (2)Sun HotSpot虛擬機把方法區叫做永久代(Permanent Generation),方法區中最終要的部分是運行時常量池。

    6、運行時常量池: 
(1)運行時常量池是方法區的一部分,自然受到方法區內存的限制,當常量池無法再申請到內存時就會拋出OutOfMemoryError異常。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章