当前位置: 首页 > 知识库问答 >
问题:

Java恒定池的目的是什么?

巢承安
2023-03-14

我目前正试图深入研究Java虚拟机的规范。我一直在网上阅读JVM书籍,其中有一个令人困惑的抽象我似乎无法理解:常量池。以下是这本书的摘录:

对于加载的每种类型,Java虚拟机都必须存储一个常量池。常量池是类型使用的一组有序常量,包括文本(字符串、整数和浮点常量)以及对类型、字段和方法的符号引用。常量池中的条目由索引引用,很像数组的元素。因为常量池包含对类型使用的所有类型、字段和方法的符号引用,所以常量池在Java程序的动态链接中起着核心作用

我对上述内容和CP总的来说有几个问题:

  1. CP是否位于中。为每种类型分类文件

共有3个答案

夏侯阳
2023-03-14

用简单的英语来说,常量池的用途是什么?

该CP是存储非常独特的恒定值的存储区域,以减少冗余:

System.err.println("Hello");
System.out.println("Hello");

在CP中只有一个字符串对象“Hello”,编译器将两行中的内容替换为同一引用。你的类文件仅包含一个Hello字符串。(其他类型相同)。

CP位于。每种类型的类文件?

是的,看这里:http://en.wikipedia.org/wiki/Java_class_file

贺亦
2023-03-14

我认为理解框架是如何使用图表构建的会有所帮助。

帧是操作数(操作指令)驻留的位置,也是动态链接发生的位置。可以说,这是一种速记方法,使用常量池来跟踪类及其成员。

每个帧包含对运行时常量池的引用。引用指向为该帧执行的方法类的常量池。此参考有助于支持动态链接。

C/C代码通常编译成一个目标文件,然后将多个目标文件链接在一起,生成一个可用的工件,如可执行文件或dll。在链接阶段,每个目标文件中的符号引用被替换为相对于最终可执行文件的实际内存地址。Java这个链接阶段是在运行时动态完成的。

编译Java文件时,对变量和方法的所有引用都作为符号引用存储在类的常量池中。符号引用是逻辑引用,而不是实际指向物理内存位置的引用。

这里有一个指向JamesBloomsJVM内部的链接,以了解更多详细信息。

邬阳
2023-03-14

常量池是的一部分。类文件(及其内存中的表示形式),其中包含运行该类代码所需的常量。

这些常量包括程序员指定的文字和编译器生成的符号引用。符号引用基本上是从代码中引用的类、方法和字段的名称。JVM使用这些引用将代码链接到它所依赖的其他类。

例如,下面的代码

System.out.println("Hello, world!");

生成以下字节码(javapoutput)

0:   getstatic       #2; //Field java/lang/System.out:Ljava/io/PrintStream;              
3:   ldc     #3; //String Hello, world!                                                  
5:   invokevirtual   #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V

#n这里是对常量池的引用。#2是对System.out字段的符号引用,#3是一个你好,世界!字符串和#4是对PrintStream.println(String)方法的符号引用。

如您所见,符号引用不仅仅是名称-例如,对方法的符号引用还包含关于其参数(Ljava/lang/String;)和返回类型(V表示无效)的信息。

您可以通过为某个类运行javap-verbose来检查该类的常量池。

 类似资料:
  • 问题内容: 当我多次(docs)运行时,每次输出都不同。 我究竟做错了什么?为什么不是恒定的? 问题答案: 由于每次调用该函数时都会随机生成盐,因此生成的密码哈希也不同。返回的哈希值包含生成的盐,因此仍可以正确验证密码。 演示: 这两个字符串不同。但包含足够的信息来验证密码,因为生成的盐包含在每个密码中: Because the random salt is for one and , the r

  • 问题内容: 我对Java中的StringPool感到困惑。我在阅读Java中的String一章时遇到了这个问题。用外行的术语,请帮助我了解StringPool的实际作用。 问题答案: 打印(即使我们不使用方法:比较字符串的正确方法) 当编译器优化你的字符串文字时,它会看到两者s和t具有相同的值,因此你只需要一个字符串对象。这是安全的,因为在中是不可变的。 结果,两者和都t指向同一个对象,节省了一些

  • 本文向大家介绍什么是CNN的池化相关面试题,主要包含被问及什么是CNN的池化时的应答技巧和注意事项,需要的朋友参考一下 池化,简言之,即取区域平均或最大,如下图所示(图引自cs231n) 上图所展示的是取区域最大,即上图左边部分中 左上角2x2的矩阵中6最大,右上角2x2的矩阵中8最大,左下角2x2的矩阵中3最大,右下角2x2的矩阵中4最大,所以得到上图右边部分的结果:6 8 3 4。

  • 与自定义线程池相比,源指Oracle留档建议在并行流时使用公共线程池。 既然公共池的线程数与CPU内核数相同,那么使用公共线程池和自定义线程池有什么区别?

  • 本文向大家介绍Java中的字符串常量池是什么?,包括了Java中的字符串常量池是什么?的使用技巧和注意事项,需要的朋友参考一下 当您将字符串存储为 JVM会直接在一个单独的内存块(称为String常量池)中创建具有给定值的String对象。 每当我们尝试创建另一个String作为 JVM会验证String常量池中是否存在具有相同值的String对象,如果不是,JVM会创建新对象而不是创建新对象,而

  • 问题内容: 我已经读了很多关于序列化的文章,它是如此的好和很棒,但是没有一个论点令人信服。我想知道是否有人真的可以告诉我通过序列化类可以真正实现的目标? 问题答案: 让我们先定义序列化,然后再讨论为什么它如此有用。 序列化只是将现有对象转换为字节数组。此字节数组表示对象的类,对象的版本以及对象的内部状态。然后可以在运行相同代码的JVM之间使用此字节数组来传输/读取对象。 我们为什么要这样做? 有以