Java內存區域

  • 程序計數器: 
    • 線程私有的,他是一塊較小的內存空間,他相當字節碼於解釋器中的指針,也就是該內存存放下一條即將執行指令的地址。字節碼解釋器就是通過改變 這個計數器的值來選擇下一條即將執行的指令。每一個線程都有一個程序計數器(內存),這樣線程切換的時候就能找到自己各個線程各自即將執行的下一條指令。 所以說是線程私有的。
  • java虛擬機棧: 
    • 線程私有的,每一個方法在執行的時候就會創建一個棧幀來存放方法的局部變量操作數棧返回地址等,當方法執行完成的時候就釋放該棧幀。 
      棧幀:虛擬機棧中是一棧幀爲單位存儲的,所以一個虛擬機棧中有很多棧幀,每一個棧幀中分爲:局部變量區(存放方法的參數和局部變量),操作數棧,方法的返回地址,動態鏈接(一般解析解階段是將部分符號引用轉換成直接應用(類加載),而動態鏈接是另外一部分的符號引用轉換成直接引用(運行時))
  • 本地方法棧: 
    • 線程私有,本地方法指的是那種不是用java語言寫的方法,java虛擬機棧只針java方法,而不是本地方法。hotspot虛擬機支持別的語言寫的方法在虛擬機上運行,本法方法棧和java虛擬機棧一樣。只是他們服務的對象不一樣而已,一個爲java方法服務,一個爲native方法服務。
  • Java堆: 
    • 線程共享的唯一的目的就是存放對象實例,不過也可能爲多個線程分配私有的buffer,也就是每個線程有自己的緩存器,java堆可以是物理上連續的,也可以是不連續的。java堆是垃圾回收器管理的主要區域,所以也叫gc堆。java堆可以分爲:新生代和老年代
  • 方法區: 
    • 線程共享的,可以理解爲gcc中所所說的靜態區,不過也不是確切的準確,因爲在hotspot虛擬機中他存放的是類中靜態變量和常量(注意是常量哦)編譯器編譯後的代碼等。因爲他能存儲常量,所以還有存儲常量的區域有一個特別的名稱,叫做常量池(包括引用和基本數據類型的常量),方法區並不是堆,這一點和靜態區很相似。所以別名叫non-heap,java堆中可以選擇不實現gc回收,但是實際上呢還是會的,只能說垃圾回收器在這個區域不活躍而已,但是回收都是回收常量池中的常量,而不是靜態變量。可以稱爲永久代。
  • 運行時常量池: 
    • 他是方法區的一部分,但是和方法區的常量池有區別,他存放的常量是在運行時產生的,而不是編譯時產生的。注意與普通方法區的區別

對象訪問

Object obj=new Object();假設這句出現待方法體中,

  • 那麼"Object obj" 則部分會映射到Java棧的本地變量表中,作爲一個reference類型數據出現,
  • "new Object()"則映射到Java堆中,形成一塊存儲了Object類型的所有數據值的結構化內存,還包括能查到此對象類型數據(如對象類型,父類,實現接口,方法等)的地址信息,
  • 而這些類型數據存儲在方法區中

那麼reference是如何訪問Java堆中對象的位置呢:

①使用句:Java堆會劃分一塊區域存儲句柄池,reference中存儲的是對象的句柄地址,句柄中包括對象實例數據和數據類型的各自的具體地址信息:

②使用直接指針:reference中直接存儲的就是對象的地址信息

兩種方式有各自的優點,使用句柄,在對象被移動的時候自需要給吧句柄中的實例數據指針,而reference本身不需要被修改

使用直接指針最大的好處是速度更快,節省了一次指針定位時間,由於對象在java中頻繁範圍,所以也是節省也是可觀的

 

 

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