Class常量池

     Class常量池可以理解为是Class文件中的资源仓库。 Class文件中除了包含类的版本、字段、方法、接口等描述信息外, 还有一项信息就是常量池(constant pool table),用于存放编译器生成的各种字面量(Literal)和符号引用(Symbolic References)。

一个class文件的16进制大体结构如下图:
Class常量池
对应的含义如下,细节可以查下oracle官方文档
Class常量池
当然我们一般不会去人工解析这种16进制的字节码文件,我们一般可以通过javap命令生成更可读的JVM字节码指令文 件:
javap -v Math.class

Classfile /E:/open/demo/target/classes/com/example/demo/test/opencv/Math.class
Last modified 2020-9-20; size 619 bytes
MD5 checksum f70c67abc97af9f0978a807380fcb072
Compiled from "Math.java"
public class com.example.demo.test.opencv.Math
minor version: 0
major version: 52
flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
#1 = Methodref #5.#26 // java/lang/Object."<init>":()V
#2 = Class #27 // com/example/demo/test/opencv/Math
#3 = Methodref #2.#26 // com/example/demo/test/opencv/Math."<init>":()V
#4 = Methodref #2.#28 // com/example/demo/test/opencv/Math.compute:()I
#5 = Class #29 // java/lang/Object
#6 = Utf8 <init>
#7 = Utf8 ()V
#8 = Utf8 Code
#9 = Utf8 LineNumberTable
#10 = Utf8 LocalVariableTable
#11 = Utf8 this
#12 = Utf8 Lcom/example/demo/test/opencv/Math;
#13 = Utf8 compute
#14 = Utf8 ()I
#15 = Utf8 a
#16 = Utf8 I
#17 = Utf8 b
#18 = Utf8 c
#19 = Utf8 main
#20 = Utf8 ([Ljava/lang/String;)V
#21 = Utf8 args
#22 = Utf8 [Ljava/lang/String;
#23 = Utf8 math
#24 = Utf8 SourceFile
#25 = Utf8 Math.java
#26 = NameAndType #6:#7 // "<init>":()V
#27 = Utf8 com/example/demo/test/opencv/Math
#28 = NameAndType #13:#14 // compute:()I
#29 = Utf8 java/lang/Object
{
public com.example.demo.test.opencv.Math();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=1, locals=1, args_size=1
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
LineNumberTable:
line 3: 0
LocalVariableTable:
Start Length Slot Name Signature
0 5 0 this Lcom/example/demo/test/opencv/Math;

public int compute();
descriptor: ()I
flags: ACC_PUBLIC
Code:
stack=2, locals=4, args_size=1
0: iconst_1
1: istore_1
2: iconst_2
3: istore_2
4: iload_1
5: iload_2
6: iadd
7: bipush 10
9: imul
10: istore_3
11: iload_3
12: ireturn
LineNumberTable:
line 6: 0
line 7: 2
line 8: 4
line 9: 11
LocalVariableTable:
Start Length Slot Name Signature
0 13 0 this Lcom/example/demo/test/opencv/Math;
2 11 1 a I
4 9 2 b I
11 2 3 c I

public static void main(java.lang.String[]);
descriptor: ([Ljava/lang/String;)V
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=2, locals=3, args_size=1
0: new #2 // class com/example/demo/test/opencv/Math
3: dup
4: invokespecial #3 // Method "<init>":()V
7: astore_1
8: aload_1
9: invokevirtual #4 // Method compute:()I
12: istore_2
13: return
LineNumberTable:
line 14: 0
line 15: 8
line 16: 13
LocalVariableTable:
Start Length Slot Name Signature
0 14 0 args [Ljava/lang/String;
8 6 1 math Lcom/example/demo/test/opencv/Math;
13 1 2 compute I
}
SourceFile: "Math.java"

常量池中主要存放两大类常量:字面量和符号引用。

字面量
字面量就是指由字母、数字等构成的字符串或者数值常量
字面量只可以右值出现,所谓右值是指等号右边的值,如:int a=1 这里的a为左值1为右值。在这个例子中1就是字面量。

int a = 1;
int b = 2;
int c = "abcdefg";

符号引用
符号引用是编译原理中的概念,是相对于直接引用来说的。主要包括了以下三类常量:

类和接口的全限定名字段的名称和描述符方法的名称和描述符
     上面的a,b就是字段名称,就是一种符号引用,还有Math类常量池里的 Lcom/example/demo/test/opencv/Math 是类的全限定名, main和compute是方法名称,()是一种UTF8格式的描述符,这些都是符号引用。
      这些常量池现在是静态信息,只有到运行时被加载到内存后,这些符号才有对应的内存地址信息,这些常量池一旦被装 入内存就变成运行时常量池了,对应的符号引用在程序加载或运行时会被转变为被加载到内存区域的代码的直接引用, 也就是我们说的动态链接了。例如,compute()这个符号引用在运行时就会被转变为compute()方法具体代码在内存中 的地址,主要通过对象头里的类型指针去转换直接引用。

Jdk1.6及之前: 有永久代, 常量池在方法区
Jdk1.7:有永久代,但已经逐步“去永久代”,常量池在堆
Jdk1.8及之后: 无永久代,常量池在元空间

字符串常量池
字符串常量池的设计思想

    字符串的分配,和其他的对象分配一样,耗费高昂的时间与空间代价,作为最基础的数据类型,大量频繁的创建 字符串,极大程度地影响程序的性能JVM为了提高性能和减少内存开销,在实例化字符串常量的时候进行了一些优化

为字符串开辟一个字符串常量池,类似于缓存区
创建字符串常量时,首先坚持字符串常量池是否存在该字符串
存在该字符串,返回引用实例,不存在,实例化该字符串并放入池中

代码示例,一些字符串局部变量操作

String str1 = "abc";
String str2 = "abc";
String str3 = "abc";
String str4 = new String("abc");
String str5 = new String("abc");
String str5 = new String("abc");

Class常量池

安全点与安全区域
安全点

安全点就是指代码中一些特定的位置,当线程运行到这些位置时它的状态是确定的,这样JVM就可以安全的进行一些操作,比 如GC等,所以GC不是想什么时候做就立即触发的,是需要等待所有线程运行到安全点后才能触发。 这些特定的安全点位置主要有以下几种:

    方法返回之前调用某个方法之后抛出异常的位置循环的末尾

安全区域

Safe Point 是对正在执行的线程设定的。
如果一个线程处于 Sleep 或中断状态,它就不能响应 JVM 的中断请求,再运行到 Safe Point 上。 因此 JVM 引入了 Safe Region。
Safe Region 是指在一段代码片段中,引用关系不会发生变化。在这个区域内的任意地方开始 GC 都是安全的。 线程在进入 Safe Region 的时候先标记自己已进入了 Safe Region,等到被唤醒时准备离开 Safe Region 时,先检查能 否离开,如果 GC 完成了,那么线程可以离开,否则它必须等待直到收到安全离开的信号为止。

原创:https://www.panoramacn.com
源码网提供WordPress源码,帝国CMS源码discuz源码,微信小程序,小说源码,杰奇源码,thinkphp源码,ecshop模板源码,微擎模板源码,dede源码,织梦源码等。

专业搭建小说网站,小说程序,杰奇系列,微信小说系列,app系列小说

Class常量池

免责声明,若由于商用引起版权纠纷,一切责任均由使用者承担。

您必须遵守我们的协议,如果您下载了该资源行为将被视为对《免责声明》全部内容的认可-> 联系客服 投诉资源
www.panoramacn.com资源全部来自互联网收集,仅供用于学习和交流,请勿用于商业用途。如有侵权、不妥之处,请联系站长并出示版权证明以便删除。 敬请谅解! 侵权删帖/违法举报/投稿等事物联系邮箱:2640602276@qq.com
未经允许不得转载:书荒源码源码网每日更新网站源码模板! » Class常量池
关注我们小说电影免费看
关注我们,获取更多的全网素材资源,有趣有料!
120000+人已关注
分享到:
赞(0) 打赏

评论抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

您的打赏就是我分享的动力!

支付宝扫一扫打赏

微信扫一扫打赏