JVM方法调用与方法区

本文详细探讨了JVM方法区的内容加载时间节点,包括类信息、静态变量、常量、代码和虚方法表,并指出方法区可能引发的OOM问题。解析调用发生在类加载的解析阶段,静态分派在编译阶段,而动态分派在运行期,通过实际类型判断重写。Java实现静态多分派和动态单分派。
摘要由CSDN通过智能技术生成

0. 方法区

0.1 内容加载的时间节点

0.1.1 类信息

==加载阶段==会将外部的class文件(二进制字节流)按照特定格式存储在方法区。
在HotSpot JVM还会在方法区实例化与这个class文件相对应的java.lang.Class类对象

0.1.2 静态变量

==准备阶段==为静态变量分配内存并设置初始值
==初始化阶段==为静态变量赋值

0.1.3 常量

三类常量:Enum,类中的static final修饰的字段,interface中的字段
在类加载完毕后,常量就会放到方法区了。

静态变量和常量都放在了方法区的==常量池==中
但是常量池的内容并非全部来自class文件中常量池的内容。运行时也有可能将新的常量放入池中,比如,String的intern()方法。
class文件中的常量池将在类加载后放入方法区的常量池。但是,方法区的常量池相对于class文件的常量池,具有动态性。

0.1.4 代码

代码存储在class文件的code属性
类加载完毕后,代码会放到方法区

对于JVM内存的其他区域的内容载入的时间节点就十分明确了
虚拟机栈:方法执行时会创建栈桢,存储局部变量,操作数,动态链接(常量池中该方法的引用),返回地址。方法执行完毕后,栈桢从栈中弹出。
Java堆:运行时实例化的对象会放到Java堆

0.1.5 虚方法表

使用虚方法表类提高动态分配是进行方法选择时搜索合适目标方法的效率。
方法表一般在类加载的连接阶段进行初始化,完成类变量初始化后,类的方法表也初始化完毕。

0.2 方法区会发生OOM吗?


在JDK1.7之前,方法区是放在永久代,而永久代的大小是固定的,频繁地调用String的intern方法(编译器会将字符串添加到常量池中),就可能导致OOM。此外,倘若一下子加载多个类,超过了永久代的大小,也会导致OOM。

在JDK1.7之后,方法区的常量池放在了堆,而类信息则放到了MetaSpace,大概长这样,

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值