<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不会执行一半就去执行其他线程的指令)


相关文章
|
9月前
|
Arthas 存储 算法
深入理解JVM,包含字节码文件,内存结构,垃圾回收,类的声明周期,类加载器
JVM全称是Java Virtual Machine-Java虚拟机JVM作用:本质上是一个运行在计算机上的程序,职责是运行Java字节码文件,编译为机器码交由计算机运行类的生命周期概述:类的生命周期描述了一个类加载,使用,卸载的整个过类的生命周期阶段:类的声明周期主要分为五个阶段:加载->连接->初始化->使用->卸载,其中连接中分为三个小阶段验证->准备->解析类加载器的定义:JVM提供类加载器给Java程序去获取类和接口字节码数据类加载器的作用:类加载器接受字节码文件。
846 55
|
4月前
|
存储 缓存 Java
我们来说一说 JVM 的内存模型
我是小假 期待与你的下一次相遇 ~
383 5
|
4月前
|
存储 缓存 算法
深入理解JVM《JVM内存区域详解 - 世界的基石》
Java代码从编译到执行需经javac编译为.class字节码,再由JVM加载运行。JVM内存分为线程私有(程序计数器、虚拟机栈、本地方法栈)和线程共享(堆、方法区)区域,其中堆是GC主战场,方法区在JDK 8+演变为使用本地内存的元空间,直接内存则用于提升NIO性能,但可能引发OOM。
|
10月前
|
Arthas 监控 Java
Arthas memory(查看 JVM 内存信息)
Arthas memory(查看 JVM 内存信息)
824 6
|
9月前
|
缓存 算法 Java
JVM深入原理(八)(一):垃圾回收
弱引用-作用:JVM中使用WeakReference对象来实现软引用,一般在ThreadLocal中,当进行垃圾回收时,被弱引用对象引用的对象就直接被回收.软引用-作用:JVM中使用SoftReference对象来实现软引用,一般在缓存中使用,当程序内存不足时,被引用的对象就会被回收.强引用-作用:可达性算法描述的根对象引用普通对象的引用,指的就是强引用,只要有这层关系存在,被引用的对象就会不被垃圾回收。引用计数法-缺点:如果两个对象循环引用,而又没有其他的对象来引用它们,这样就造成垃圾堆积。
236 0
|
9月前
|
算法 Java 对象存储
JVM深入原理(八)(二):垃圾回收
Java垃圾回收过程会通过单独的GC线程来完成,但是不管使用哪一种GC算法,都会有部分阶段需要停止所有的用户线程。这个过程被称之为StopTheWorld简称STW,如果STW时间过长则会影响用户的使用。一般来说,堆内存越大,最大STW就越长,想减少最大STW,就会减少吞吐量,不同的GC算法适用于不同的场景。分代回收算法将整个堆中的区域划分为新生代和老年代。--超过新生代大小的大对象会直接晋升到老年代。
232 0
|
缓存 Prometheus 监控
Elasticsearch集群JVM调优设置合适的堆内存大小
Elasticsearch集群JVM调优设置合适的堆内存大小
2388 1
|
存储 设计模式 监控
快速定位并优化CPU 与 JVM 内存性能瓶颈
本文介绍了 Java 应用常见的 CPU & JVM 内存热点原因及优化思路。
1190 166
|
11月前
|
存储 缓存 算法
JVM简介—1.Java内存区域
本文详细介绍了Java虚拟机运行时数据区的各个方面,包括其定义、类型(如程序计数器、Java虚拟机栈、本地方法栈、Java堆、方法区和直接内存)及其作用。文中还探讨了各版本内存区域的变化、直接内存的使用、从线程角度分析Java内存区域、堆与栈的区别、对象创建步骤、对象内存布局及访问定位,并通过实例说明了常见内存溢出问题的原因和表现形式。这些内容帮助开发者深入理解Java内存管理机制,优化应用程序性能并解决潜在的内存问题。
572 29
JVM简介—1.Java内存区域
|
11月前
|
缓存 监控 算法
JVM简介—2.垃圾回收器和内存分配策略
本文介绍了Java垃圾回收机制的多个方面,包括垃圾回收概述、对象存活判断、引用类型介绍、垃圾收集算法、垃圾收集器设计、具体垃圾回收器详情、Stop The World现象、内存分配与回收策略、新生代配置演示、内存泄漏和溢出问题以及JDK提供的相关工具。
JVM简介—2.垃圾回收器和内存分配策略