全局变量存放在哪里?

全局变量存放在哪里?

看了下深入java虚拟机,有这么几个问题,希望大神们给解决下,1.final、static分别修饰的变量会放到哪里?2.看对栈的描述是局部变量放到栈中,那么全局变量放到哪里?

RednaxelaFX从事JVM研发

如风网事BravoMao数据挖掘li mo 等人赞同

这里只讨论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的区域中。请参考传送门:http://www.valleytalk.org/wp-content/uploads/2011/05/Java_Program_in_Action_20110727.pdf,第121页

<- 这个做法跟 @代码豆 大大提到的CLR把静态变量放在MethodTable对象里是一个思路。

在Oracle JDK7 / OpenJDK7及之后的HotSpot VM里,静态变量存储在java.lang.Class对象末尾的隐藏字段里,而java.lang.Class对象存储在普通的Java heap里(不在PermGen里了)。

时间: 2024-10-10 06:22:53

全局变量存放在哪里?的相关文章

C语言中全局变量存放在哪个位置?

今年软考的时候,遇到了这个题目,表示不解,然后考完之后去查了一下百度,才发现自己选错.全局变量存放在静态存储区,位置是固定的. 局部变量在栈空间,栈地址是不固定的.栈:就是那些由编译器在需要的时候分配,在不需要的时候自动清楚的变量的存储区.里面的变量通常是局部变量.函数参数等.堆:就是那些由new分配的内存块,他们的释放编译器不去管,由我们的应用程序去控制,一般一个new就要对应一个delete.如果程序员没有释放掉,那么在程序结束后,操作系统会自动回收.自由存储区:就是那些由malloc等分配

c语言全局变量和局部变量问题汇总

1.局部变量是否能和全局变量重名? 答:能,局部会屏蔽全局.要用全局变量,须要使用"::" 局部变量能够与全局变量同名,在函数内引用这个变量时,会用到同名的局部变量,而不会用到全局变量.对于有些编译器而言,在同一个函数内能够定义多个同名的局部变量,比方在两个循环体内都定义一个同名的局部变量,而那个局部变量的作用域就在那个循环体内. 2.怎样引用一个已经定义过的全局变量? 答:extern 能够用引用头文件的方式,也能够用externkeyword,假设用引用头文件方式来引用某个在头文件

局部变量、全局变量、堆、栈

预备知识—程序的内存分配 一个由C/C++编译的程序占用的内存分为以下几个部分 栈区(stack)— 由编译器自动分配释放,存放函数的参数值,局部变量的值等.其操作方式类似于数据结构中的栈. 堆区(heap) — 一般由程序员分配释放,若程序员不释放,程序结束时可能由OS回收 .注意它与数据结构中的堆是两回事,分配方式倒是类似于链表. 全局区(静态区)(static)—,全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域, 未初始化的全局变量.未初始化的静态变量在相邻的另

比较全局变量、全局静态变量、局部变量、局部静态变量的区别

比较全局变量.全局静态变量.局部变量.局部静态变量的区别,他们在编译完后存储位置在什么地方.初始化值在什么地方.内存什么时候分配.赋初值对这些变量有哪些影响等.要弄清楚这些问题,首先要弄清楚下面几个知识点. C语言分下面几个存储区: 1.栈区(stack) 由编译器在需要的时候自动分配释放,在不需要的时候就自动清除的变量存储区.通常存放的变量是函数的参数值.局部变量的值等,其操作方式类似于数据结构中的栈. 2.堆区(heap) 一般由程序员去分配释放,和编译器完全没有关系,直接由我们的应用程序去

linux内核分析之内存管理

1.struct page 1 /* Each physical page in the system has a struct page associated with 2 * it to keep track of whatever it is we are using the page for at the 3 * moment. Note that we have no way to track which tasks are using 4 * a page, though if it

PHP代码优化技巧大盘点

原文:PHP代码优化技巧大盘点 PHP优化的目的是花最少的代价换来最快的运行速度与最容易维护的代码.本文给大家提供全面的优化技巧. 1.echo比print快. 2.使用echo的多重参数代替字符串连接. 3.在执行for循环之前确定最大循环数,不要每循环一次都计算最大值,最好运用foreach代替. 4.对global变量,应该用完就unset()掉. 5.用单引号代替双引号来包含字符串,这样做会更快一些.因为PHP会在双引号包围的字符串中搜寻变量,单引号则不会. 6.函数代替正则表达式完成相

【转】朱兆祺带你一步一步学习嵌入式(连载)

原文网址:http://bbs.elecfans.com/jishu_357014_2_1.html#comment_top  从最初涉及嵌入式Linux开始到现在,深深的知道嵌入式的每一步学习都是举步维艰.从去年11月份开始,我就着手整理各种学习资料,希望推动嵌入式学习的前进贡献自己微不足道的一份力量.从去年到现在,将C语言的学习经验整理成<攻破C语言笔试与机试陷阱及难点>(现在仍在更新),这份资料已经在电子发烧友论坛的单片机论坛连载(http://bbs.elecfans.com/jish

请问android直接post请求登录地址成功后,webview还是现实登录界面

============问题描述============ 之前登录是这样做的: webview.loadUrl(调js登录的方法),  这个js方法其实也就是post请求一个登录地址 现在我直接做一个登录界面,里面直接post这个请求,把需要的数据传过去,返回成功. 但是我回到webview刷新一下,还是显示网页的登录界面.按道理应该是显示用户信息界面. 后来发现是cookie的问题.但是这个cookie一点都不熟悉 问题大概就是: android应用登录界面post请求登录地址成功后 webv

【Linux 驱动】设备驱动程序再理解

学习设备驱动编程也有一段时间了,也写过了几个驱动程序,因此有对设备驱动程序有了一些新的理解和认识,总结一下.学习设备驱动编程也有一段时间了,也写过了几个驱动程序,因此有对设备驱动程序有了一些新的理解和认识,总结一下. ★什么是驱动程序 刚开始学习设备驱动程序的时候,产生了许多的问题.什么是驱动程序?驱动程序是干嘛的?它是如何工作的?它又是如何跟操作系统联系起来的?一系列的问题,现在有些地方还是不一定清楚,但是相比起刚开始的那个阶段,感觉自己还是清楚了很多. 设备驱动程序说白了(实质)就是为应用程