【方法区】运行时数据区——方法区

概述

本质上是Java语言编译后代码 存储区域,它存储每一个类的结构信息,例如:运行时常量池、成员变量、方法数据、构造方法和普通 方法的字节码指令等内容。很多语言都有类似区域。

方法区的具体实现有两种:永久代(PermGen)、元空间(Metaspace)

方法区存储的数据:

  1. Class信息:
    1. 类型信息,比如Class(com.hero.User类)
    2. 方法信息,比如Method(方法名称、方法参数列表、方法返回值信息)
    3. 字段信息,比如Field(字段类型,字段名称需要特殊设置才能保存的住)
    4. 类变量(静态变量)JDK1.7之后,转移到堆中存储
    5. 方法表(方法调用的时候) 在A类的main方法中去调用B类的method1方法,是根据B类的方法表去查找合适的方法,进行调用的。
  2. 运行时常量池(字符串常量池):从class中的常量池加载而来,JDK1.7之后,转移到堆中存储
    1. 字面量类型
    2. 引用类型–>内存地址
  3. JIT编译器编译之后的代码缓存

方法区变迁

移除永久代的工作从JDK1.7就开始了。JDK1.7中,存储在永久代的部分数据就已经转移到了Java Heap。但永久代仍存在于JDK1.7中,并没完全移除,譬如:字面量转移到了java heap;类的静态变量(class statics)转移到了java heap。

字符串常量池

** class常量池:一个class文件只有一个class常量池 **

  • 字面量:数值型(int、float、long、double)、双引号引起来的字符串值等
  • 符号引用:Class、Method、Field等

**运行时常量池:一个class对象有一个运行时常量池 **

同上

** 字符串常量池:全局只有一个字符串常量池 **


数据结构

StringTable, StringTable里面保存了字符串的引用 ,类似于hash表,是数组加链表,可以加速查找速度

如何查找字符串
  • 根据字符串的hashcode找到对应entry
  • 如果没有冲突,它可能只是一个entry
  • 如何有冲突,它可能是一个entry的链表,然后Java再遍历链表,匹配引用对应的字符串
  • 如果找到字符串,返回引用
  • 如果找不到字符串,在使用intern()方法的时候,会将intern()方法调用者的引用放入到stringtable 中
什么字符串放入字符串常量池
  • 单独使用””引号创建的字符串都是常量,编译期就已经确定存储到String Pool中。
  • 使用new String(“”)创建的对象会存储到heap中,是运行期新创建的。
  • 使用只包含常量的字符串连接符如”aa”+”bb”创建的也是常量,编译期就能确定已经存储到String Pool中。
  • 使用包含变量的字符串连接如”aa”+s创建的对象是运行期才创建的,存储到heap中
  • 运行期调用String的intern()方法可以向String Pool中动态添加对象。
案例

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值