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


相关文章
|
7天前
|
存储 监控 算法
深入探索Java虚拟机(JVM)的内存管理机制
本文旨在为读者提供对Java虚拟机(JVM)内存管理机制的深入理解。通过详细解析JVM的内存结构、垃圾回收算法以及性能优化策略,本文不仅揭示了Java程序高效运行背后的原理,还为开发者提供了优化应用程序性能的实用技巧。不同于常规摘要仅概述文章大意,本文摘要将简要介绍JVM内存管理的关键点,为读者提供一个清晰的学习路线图。
|
8天前
|
缓存 监控 算法
Python内存管理:掌握对象的生命周期与垃圾回收机制####
本文深入探讨了Python中的内存管理机制,特别是对象的生命周期和垃圾回收过程。通过理解引用计数、标记-清除及分代收集等核心概念,帮助开发者优化程序性能,避免内存泄漏。 ####
20 3
|
14天前
|
算法 Java 开发者
Java内存管理与垃圾回收机制深度剖析####
本文深入探讨了Java虚拟机(JVM)的内存管理机制,特别是其垃圾回收机制的工作原理、算法及实践优化策略。不同于传统的摘要概述,本文将以一个虚拟的“城市环卫系统”为比喻,生动形象地揭示Java内存管理的奥秘,旨在帮助开发者更好地理解并调优Java应用的性能。 ####
|
16天前
|
Java
JVM内存参数
-Xmx[]:堆空间最大内存 -Xms[]:堆空间最小内存,一般设置成跟堆空间最大内存一样的 -Xmn[]:新生代的最大内存 -xx[use 垃圾回收器名称]:指定垃圾回收器 -xss:设置单个线程栈大小 一般设堆空间为最大可用物理地址的百分之80
|
17天前
|
Java
JVM运行时数据区(内存结构)
1)虚拟机栈:每次调用方法都会在虚拟机栈中产生一个栈帧,每个栈帧中都有方法的参数、局部变量、方法出口等信息,方法执行完毕后释放栈帧 (2)本地方法栈:为native修饰的本地方法提供的空间,在HotSpot中与虚拟机合二为一 (3)程序计数器:保存指令执行的地址,方便线程切回后能继续执行代码
18 3
|
17天前
|
存储 缓存 监控
Elasticsearch集群JVM调优堆外内存
Elasticsearch集群JVM调优堆外内存
42 1
|
6天前
|
存储 监控 算法
Java内存管理的艺术:深入理解垃圾回收机制####
本文将引领读者探索Java虚拟机(JVM)中垃圾回收的奥秘,解析其背后的算法原理,通过实例揭示调优策略,旨在提升Java开发者对内存管理能力的认知,优化应用程序性能。 ####
20 0
|
17天前
|
缓存 Prometheus 监控
Elasticsearch集群JVM调优设置合适的堆内存大小
Elasticsearch集群JVM调优设置合适的堆内存大小
150 1
|
2月前
|
存储 安全 Java
jvm 锁的 膨胀过程?锁内存怎么变化的
【10月更文挑战第3天】在Java虚拟机(JVM)中,`synchronized`关键字用于实现同步,确保多个线程在访问共享资源时的一致性和线程安全。JVM对`synchronized`进行了优化,以适应不同的竞争场景,这种优化主要体现在锁的膨胀过程,即从偏向锁到轻量级锁,再到重量级锁的转变。下面我们将详细介绍这一过程以及锁在内存中的变化。
40 4
|
27天前
|
Arthas 监控 Java
JVM进阶调优系列(9)大厂面试官:内存溢出几种?能否现场演示一下?| 面试就那点事
本文介绍了JVM内存溢出(OOM)的四种类型:堆内存、栈内存、元数据区和直接内存溢出。每种类型通过示例代码演示了如何触发OOM,并分析了其原因。文章还提供了如何使用JVM命令工具(如jmap、jhat、GCeasy、Arthas等)分析和定位内存溢出问题的方法。最后,强调了合理设置JVM参数和及时回收内存的重要性。