Java虛擬機——Java內存區域⽅法區

1:是什麼

  • 是各個線程共享的內存區域,它⽤於存儲已被虛擬機加載的類信息、常量、靜態變量、即時 編譯器編譯後的代碼等數據
  • 什麼是類信息:類版本號、⽅法、接⼝
  1. 方法區(Method Area)存儲的類信息

        對每個加載的類型(類class、接口interface、枚舉enum、註解annotation),JVM必須在方法區中存儲以下類型信息:

       這個類型的完整有效名稱(全名=包名.類名)

       這個類型直接父類的完整有效名稱( java.lang.Object除外,其他類型若沒有聲明父類,默認父類是Object)

       這個類型的修飾符(public、abstract、final的某個子集)

       這個類型直接接口的一個有序列表 
       除此之外還方法區(Method Area)存儲類信息還有

           類型的常量池( constant pool),域(Field)信息,方法(Method)信息,除了常量外的所有靜態(static)變量

      2 方法區(Method Area)存儲的常量

              static final修飾的成員變量都存儲於 方法區(Method Area)中
           2.1方法區(Method Area)存儲的靜態變量
              靜態變量又稱爲類變量,類中被static修飾的成員變量都是靜態變量(類變量)

             靜態變量之所以又稱爲類變量,是因爲靜態變量和類關聯在一起,隨着類的加載而存在於方法區(而不是堆中)

             八種基本數據類型(byte、short、int、long、float、double、char、boolean)的靜態變量會在方法區開闢空間,並將對應的值存儲在方法方法區,對於引用類型的靜態變量如果未用new關鍵字爲引用類型的靜態變量分配對象(如:static Object obj;)那麼對象的引用obj會存儲在方法區中,併爲其指定默認值null;若,對於引用類型的靜態變量如果用new關鍵字爲引用類型的靜態變量分配對象(如:static Person person = new Person();),那麼對象的引用person 會存儲在方法區中,並且該對象在堆中的地址也會存儲在方法區中(注意此時靜態變量只存儲了對象的堆地址,而對象本身仍在堆內存中);這個過程還涉及到靜態變量初始化問題

      3  方法區(Method Area)存儲的方法(Method)
程序運行時會加載類編譯生成的字節碼,這個過程中靜態變量(類變量)和靜態方法及普通方法對應的字節碼加載到方法區。但是!!!方法區中沒有實例變量,這是因爲,類加載先於對應類對象的產生,而實例變量是和對象關聯在一起的,對象存放在堆裏面,所以方法區中沒有實例變量

靜態變量(類變量)和靜態方法及普通方法在方法區(Method Area)存儲方式是有區別的
此部分內容參考:https://blog.csdn.net/u013241673/article/details/78574770

2:爲什麼? 

  • 內存中存放類信息、靜態變量等數據,屬於線程共享的⼀塊區域
  • Hotspot使⽤永久代來實現⽅法區 JRockitIBM J9VM Java堆⼀樣管理這部分內存

 3:特點?

 

  • 在JDK1.6及之前,運行時常量池是方法區的一個部分,同時方法區裏面存儲了類的元數據信息、靜態變量、即時編譯器編譯後的代碼(比如spring 使用IOC或者AOP創建bean時,或者使用cglib,反射的形式動態生成class信息等)等。
  • 在JDK1.7及以後,JVM已經將運行時常量池從方法區中移了出來,在JVM堆開闢了一塊區域存放常量池。並⾮數據進⼊了⽅法區就如永久代的名字⼀樣永久存在了。這區域的內存回收⽬標主要是針對常量池的回收和對類型的卸載
  • ⽅法區也會拋出OutofMemoryError,當它⽆法滿⾜內存分配需求時

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章