<JVM上篇:内存与垃圾回收篇>07-方法区(三)

简介: <JVM上篇:内存与垃圾回收篇>07-方法区

7.4.4. 运行时常量池


运行时常量池(Runtime Constant Pool)是方法区的一部分。

常量池表(Constant Pool Table)是 Class 文件的一部分,用于存放编译期生成的各种字面量与符号引用,这部分内容将在类加载后存放到方法区的运行时常量池中。

字节码中的常量池存放的都是符号引用,链接解析阶段将符号引用转化为直接引用.所以方法区的运行区常量池里面存放的都是直接引用.

运行时常量池,在加载类和接口到虚拟机后,就会创建对应的运行时常量池。

JVM 为每个已加载的类型(类或接口)都维护一个常量池。池中的数据项像数组项一样,是通过索引访问的。

运行时常量池中包含多种不同的常量,包括编译期就已经明确的数值字面量,也包括到运行期解析后才能够获得的方法或者字段引用。此时不再是常量池中的符号地址了,这里换为真实地址。

运行时常量池,相对于 Class 文件常量池的另一重要特征是:具备动态性。

以String.intern()为例,编译器会将字符串添加到常量池中(StringTable维护),并返回指向该常量的引用

运行时常量池类似于传统编程语言中的符号表(symboltable),但是它所包含的数据却比符号表要更加丰富一些。

当创建类或接口的运行时常量池时,如果构造运行时常量池所需的内存空间超过了方法区所能提供的最大值,则 JVM 会抛 OutOfMemoryError 异常。

深入解析动态性:


动态性是运行时常量池可以动态的往里面添加本来没有的信息

而常量池,只能放代码中存在的信息,在编译期间,就确定了,不会再得到更改

运行时常量池,则可以通过代码动态的往里面塞信息。


7.5. 方法区使用举例

public class MethodAreaDemo {
    public static void main(String args[]) {
        int x = 500;
        int y = 100;
        int a = x / y;
        int b = 50;
        System.out.println(a+b);
    }
}


五个本地变量,所以本地变量表尾5. args存在下标为0的位置上


cd9b2a88a78a7565b1ee1e0fa9b4e8e6.png


将500放入操作数栈,然后赋值给变量x中,并将x存放到局部变量表中.


a3fa5f4718cc0f8f629c7ee343bd6c38.png

f5cffc72ae4884c175ed0b0b8757487e.png


将100放入操作数栈,然后赋值给变量y中,并将y存放到局部变量表中.


c629fbfdaae2933935b015bfa3f2baf6.png

692908400668791ac383561affed3520.png


读取本地变量表下标为1、2的变量,将其放入到操作数栈中(等待运算)


c82df4feb85da649444b2f8f0ee97d73.png33b8dadc28fc25d41931b0d30e448004.png

c82df4feb85da649444b2f8f0ee97d73.png


进行除法运算,并将结果存放到操作数栈中。之后将结果赋值给a,并存放到局部变量表中。

87ed8e32bd715e564c20d87934e0d628.png

将50放入操作数栈,然后赋值给变量b中,并将b存放到局部变量表中.


daa0b7143f91abb09924d8181f1fc807.png

获取#2(System.out.printlen)的值,并将其放入操作数栈中.


dfba814e0c1b198df7175fe93284c3e0.png


将本地变量表下标为3、4的加入到操作数栈中,并执行加操作运算。


35be7c27bee2aa8c0930cffbefa07cd8.png

5f2935ec0858f5a74f512018e582f19c.png

f584ed9e2b6d99499b2a451a63f12449.png


弹出操作数栈中的参数,传入 # 2对应的方法(System.out.println) ,进行打印操作。


b4428f7f351048601296fe211c40185e.png


执行return指令,结束方法.


bf50cc494594b4588794984df6448303.png


图解纠错


程序计数器里面应该保存的是当前执行指令的下一条指令地址.


分析:PC计数器保存的是当前指令的下一条指令地址。当前指令执行完毕,CPU切换到其他线程,执行另外一个线程的指令。 当CPU再次切换回来时,从PC计数器拿到下一条要执行的指令继续进行执行。


(CPU不会执行一半就去执行其他线程的指令)


相关文章
|
4天前
|
存储 监控 算法
【JVM】如何定位、解决内存泄漏和溢出
【JVM】如何定位、解决内存泄漏和溢出
12 0
|
4天前
|
算法 安全 Java
JVM系列4-垃圾收集器与内存分配策略(二)
JVM系列4-垃圾收集器与内存分配策略(二)
10 0
JVM系列4-垃圾收集器与内存分配策略(二)
|
4天前
|
存储 监控 算法
JVM系列4-垃圾收集器与内存分配策略(一)
JVM系列4-垃圾收集器与内存分配策略(一)
14 0
|
9天前
|
Java
JDK8中JVM堆内存划分
JDK8中JVM堆内存划分
11 0
|
10天前
|
Java 数据库连接 图形学
JVM内存泄漏检测与处理
JVM内存泄漏检测与处理
9 0
|
10天前
|
存储 机器学习/深度学习 Java
探索JVM 内存分配
探索JVM 内存分配
9 0
|
20小时前
|
消息中间件 存储 Kafka
实时计算 Flink版产品使用问题之 从Kafka读取数据,并与两个仅在任务启动时读取一次的维度表进行内连接(inner join)时,如果没有匹配到的数据会被直接丢弃还是会被存储在内存中
实时计算Flink版作为一种强大的流处理和批处理统一的计算框架,广泛应用于各种需要实时数据处理和分析的场景。实时计算Flink版通常结合SQL接口、DataStream API、以及与上下游数据源和存储系统的丰富连接器,提供了一套全面的解决方案,以应对各种实时计算需求。其低延迟、高吞吐、容错性强的特点,使其成为众多企业和组织实时数据处理首选的技术平台。以下是实时计算Flink版的一些典型使用合集。
|
2天前
|
存储 小程序 编译器
【C语言基础】:数据在内存中的存储
【C语言基础】:数据在内存中的存储
|
3天前
|
存储 C++
C primer plus 学习笔记 第12章 存储类别、链接和内存管理
C primer plus 学习笔记 第12章 存储类别、链接和内存管理
|
10天前
|
存储 编译器 C语言
C语言学习记录——数据的存储(数据类型、类型的基本归类、整型在内存中的存储、大小端介绍、浮点型在内存中的存储)二
C语言学习记录——数据的存储(数据类型、类型的基本归类、整型在内存中的存储、大小端介绍、浮点型在内存中的存储)二
11 0