【学习心得】由18年真题引起的java静态成员变量存放位置-方法区的研究

   18年真题中对静态成员变量在内存中的分配位置给出了两种选择:栈或者堆,然而在查询相关资料和进行试验后,我们发现真正答案并非是这两者,而是方法区。

  一.方法区与栈、堆之间的关系

       就考题而言,静态成员变量可以认为是在堆中分配,因为《Java虚拟机规范》中说明:“所有的方法区在逻辑上是属于堆的一部分”,但是对于HotSpotJVM而言,方法区还有一个别名叫做Non- Heap (非堆),目的就是要和堆分开。所以,方法区看作是一块独立于Java堆的内存空间。

方法区中存有对象类型信息,这个意义上说三者的交互关系可以用下图表示。

二.方法区性质与内部结构

    1.方法区与Java堆一样,是各个线程共享的内存区域。其具有以下性质:

    (1)方法区在JVM启动的时候被创建,并且它的实际的物理内存空间中和Java堆区一样都可以是不连续的。
    (2)方法区的大小,跟堆空间一样,可以选择固定大小或者可扩展。.
    (3)方法区的大小决定了系统可以保存多少个类,如果系统定义了太多的类,导致方法区溢出,虚拟机同样会抛出内存溢出错误

     2.内部结构:

     《深入理解Java虚拟机》书中对方法区存储内容描述如下:它用于存储已被虚拟机加载的类型信息、常量、静态变量、即时编译器编译后的代码缓存等。

     (1)运行时常量池:运行时常量池是方法区的一部分。而常量池表是Class文件的一部分,用于存放编译期间生成的各种字面量与符号引用,这部分内容将在类加载后存放到方法区的运行时常量池中。在加载类和接口到虚拟机后,就会创建对应的运行时常量池。

     (2)类型信息:对每个加载的类型如类、接口等,JVM必须在方法区中存储以下类型信息:
①这个类型的完整有效名称(全名=包名.类名)
②这个类型直接父类的完整有效名(对于interface或是java . lang . object,都没有父类)
③这个类型的修饰符(public, abstract, final的某个 子集)
④这个类型直接接口的一个有序列表
     (3)域信息:JVM必须在方法区中保存类型的所有域的相关信息以及域的声明顺序。域的相关信息包括: 域名称、 域类型、域修饰符(public, private等)
     (4)方法信息:JVM必须保存所有方法的以下信息,同域信息一样包括声明顺序:方法名称、方法的返回类型(或void)、方法参数的数量和类型(按顺序)、方法的修饰符(public, private等)
     (5)注意non-final的类变量,随着类的加载而加载,它们成为类数据在逻辑上的一部分。而被声明为final的类变量的处理方法则不同,每个全局常量在编译的时候就会被分配了。

       
 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值