JVM 常量池、运行时常量池、字符串常量池

常量池:

  即class文件常量池,是class文件的一部分,用于保存编译时确定的数据。

       保存的内容如下图:

 

  

 

 1 D:\java\test\out\production\test>javap -verbose mainTest
 2 Classfile /D:/java/test/out/production/test/mainTest.class
 3   Last modified 2019年4月22日; size 507 bytes
 4   MD5 checksum 08699c6d713bc8967a8daea381ce23c1
 5   Compiled from "mainTest.java"
 6 public class mainTest
 7   minor version: 0
 8   major version: 55
 9   flags: (0x0021) ACC_PUBLIC, ACC_SUPER
10   this_class: #4                          // mainTest
11   super_class: #5                         // java/lang/Object
12   interfaces: 0, fields: 1, methods: 2, attributes: 1
13 Constant pool:
14    #1 = Methodref          #5.#25         // java/lang/Object."<init>":()V
15    #2 = Fieldref           #4.#26         // mainTest.age2:I
16    #3 = String             #27            // sss
17    #4 = Class              #28            // mainTest
18    #5 = Class              #29            // java/lang/Object
19    #6 = Utf8               age2
20    #7 = Utf8               I
21    #8 = Utf8               <init>
22    #9 = Utf8               ()V
23   #10 = Utf8               Code
24   #11 = Utf8               LineNumberTable
25   #12 = Utf8               LocalVariableTable
26   #13 = Utf8               this
27   #14 = Utf8               LmainTest;
28   #15 = Utf8               main
29   #16 = Utf8               ([Ljava/lang/String;)V
30   #17 = Utf8               args
31   #18 = Utf8               [Ljava/lang/String;
32   #19 = Utf8               name
33   #20 = Utf8               Ljava/lang/String;
34   #21 = Utf8               nick
35   #22 = Utf8               age
36   #23 = Utf8               SourceFile
37   #24 = Utf8               mainTest.java
38   #25 = NameAndType        #8:#9          // "<init>":()V
39   #26 = NameAndType        #6:#7          // age2:I
40   #27 = Utf8               sss
41   #28 = Utf8               mainTest
42   #29 = Utf8               java/lang/Object
43 {
44   public mainTest();
45     descriptor: ()V
46     flags: (0x0001) ACC_PUBLIC
47     Code:
48       stack=2, locals=1, args_size=1
49          0: aload_0
50          1: invokespecial #1                  // Method java/lang/Object."<init>":()V
51          4: aload_0
52          5: bipush        22
53          7: putfield      #2                  // Field age2:I
54         10: return
55       LineNumberTable:
56         line 1: 0
57         line 2: 4
58       LocalVariableTable:
59         Start  Length  Slot  Name   Signature
60             0      11     0  this   LmainTest;
61 
62   public static void main(java.lang.String[]);
63     descriptor: ([Ljava/lang/String;)V
64     flags: (0x0009) ACC_PUBLIC, ACC_STATIC
65     Code:
66       stack=1, locals=4, args_size=1
67          0: ldc           #3                  // String sss
68          2: astore_1
69          3: ldc           #3                  // String sss
70          5: astore_2
71          6: bipush        25
72          8: istore_3
73          9: return
74       LineNumberTable:
75         line 4: 0
76         line 5: 3
77         line 6: 6
78         line 7: 9
79       LocalVariableTable:
80         Start  Length  Slot  Name   Signature
81             0      10     0  args   [Ljava/lang/String;
82             3       7     1  name   Ljava/lang/String;
83             6       4     2  nick   Ljava/lang/String;
84             9       1     3   age   I
85 }
86 SourceFile: "mainTest.java"
View Code

 

运行时常量池:

  Java语言并不要求常量一定只能在编译期产生,运行期间也可能产生新的常量,这些常量被放在运行时常量池中。

  类加载后,常量池中的数据会在运行时常量池中存放

  这里所说的常量包括:基本类型包装类(包装类不管理浮点型,整形只会管理-128到127)和String(也可以通过String.intern()方法可以强制将String放入常量池)

 

字符串常量池:

  HotSpot VM里,记录interned string的一个全局表叫做StringTable,它本质上就是个HashSet<String>。注意它只存储对java.lang.String实例的引用,而不存储String对象的内容

 

jdk 1.7后,移除了方法区间,运行时常量池和字符串常量池都在堆中。

 

posted @ 2019-04-22 11:31  那天ws  阅读(13795)  评论(6编辑  收藏  举报