1. 程式人生 > >JVM 常量池、運行時常量池、字符串常量池

JVM 常量池、運行時常量池、字符串常量池

methods pen one jdk 1.7 number open nature isp var

常量池:

  即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後,移除了方法區間,運行時常量池和字符串常量池都在堆中。

JVM 常量池、運行時常量池、字符串常量池