全局變量存放在哪里?


看了下深入java虛擬機,有這么幾個問題,希望大神們給解決下,1.final、static分別修飾的變量會放到哪里?2.看對棧的描述是局部變量放到棧中,那么全局變量放到哪里?
 
這里只討論Java/JVM層面的概念。

Java/JVM的抽象概念里沒有“全局變量”這種概念。
如果一個JVM是用C/C++實現的,那么在實現層里用到的“全局變量”就放在實現語言的全局變量所存儲的位置,跟Java/JVM自身沒關系。

題主說的“全局變量”多半實際想問的是Java層面的“靜態變量”。下面再說。

在Java層面上,變量的存儲種類(storage class)可以粗略分為3種:
  1. 局部變量/方法參數,在方法體中/參數列表中聲明,操作的Java字節碼為xload / xstore / iinc
  2. 成員字段,在類中聲明,操作的Java字節碼為getfield / putfield。
    1. A field that is not declared static (sometimes called a non-static field) is called an instance variable. Whenever a new instance of a class is created (§12.5), a new variable associated with that instance is created for every instance variable declared in that class or any of its superclasses.
  3. 靜態變量,在類中聲明,操作的Java字節碼為getstatic / putstatic。
    1. If a field is declared static, there exists exactly one incarnation of the field, no matter how many instances (possibly zero) of the class may eventually be created. A static field, sometimes called a class variable, is incarnated when the class is initialized (§12.4).
(其實還有一種特殊的,閉包捕獲的變量。那個其實是Java語言層面的語法糖,實際實現會用成員字段來實現,所以不單獨講了)

static在Java里是一種storage modifier(存儲修飾符),它會影響變量的存儲種類;
final在Java里則不是一種存儲修飾符,不影響變量的存儲種類。

所以,被final修飾的變量,該存哪兒存哪兒,跟final與否根本沒關系;
被static修飾的變量是靜態變量,從JVM規范層面看,它會存儲在“方法區”(method area)這個運行時數據區里。
Chapter 2. The Structure of the Java Virtual Machine
2.5.4. Method Area

The Java Virtual Machine has a method area that is shared among all Java Virtual Machine threads. The method area is analogous to the storage area for compiled code of a conventional language or analogous to the "text" segment in an operating system process. It stores per-class structures such as the run-time constant pool, field and method data, and the code for methods and constructors, including the special methods (§2.9) used in class and instance initialization and interface initialization.

而同樣從JVM規范層面看,Java的局部變量與參數則存放在JVM棧上:
2.5.2. Java Virtual Machine Stacks

Each Java Virtual Machine thread has a private Java Virtual Machine stack, created at the same time as the thread. A Java Virtual Machine stack stores frames (§2.6). A Java Virtual Machine stack is analogous to the stack of a conventional language such as C: it holds local variables and partial results, and plays a part in method invocation and return. Because the Java Virtual Machine stack is never manipulated directly except to push and pop frames, frames may be heap allocated. The memory for a Java Virtual Machine stack does not need to be contiguous.


“方法區”是JVM規范所描述的抽象概念。在實際的JVM實現中,它不一定是由單一的特殊區域所實現。

舉例來說,作為一種JVM實現,HotSpot VM的不同版本就會把靜態變量放在不同的地方。
在Sun JDK6 / OpenJDK6或以前的HotSpot VM里,靜態變量存儲在instanceKlass對象的末尾,而instanceKlass對象存儲在一個由GC管理的、名為Permanent Generation的區域中。請參考傳送門: ,第121頁

<- 這個做法跟  @代碼豆 大大提到的CLR把靜態變量放在MethodTable對象里是一個思路。

在Oracle JDK7 / OpenJDK7及之后的HotSpot VM里,靜態變量存儲在java.lang.Class對象末尾的隱藏字段里,而java.lang.Class對象存儲在普通的Java heap里(不在PermGen里了)。
 
 
 
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM