本文主要研究一下jvm的StringTable及SymbolTablehtml
在java7的時候將字符串常量池移到java heap,字符串常量池被限制在整個應用的堆內存中,在運行時調用String.intern()增長字符串常量不會使永久代OOM了。使用-XX:StringTableSize能夠設置StringTableSize,默認是65536java8的時候去除PermGen,將其中的方法區移到non-heap中的Metaspace,於是SymbolTable也跟隨Metaspace移到了non-heap中java
symbolic references in Runtime Constant Pool
Loading
)、鏈接(Linking
)、初始化(Initialization
)這三個步驟Verification
)、準備(Preparation
)、解析(Resolution
)三個階段;初始化階段將一個類中全部被static關鍵字標識的代碼統一執行一遍,若是執行的是靜態變量,那麼就會使用用戶指定的值覆蓋以前在準備階段設置的初始值;若是執行的是static代碼塊,那麼在初始化階段,JVM就會執行static代碼塊中定義的全部操做Linking
)步驟裏頭的解析(Resolution
)階段,須要將常量池中全部的符號引用(classes、interfaces、fields、methods referenced in the constant pool
)轉爲直接引用(獲得類或者字段、方法在內存中的指針或者偏移量,以便直接調用該方法
)SymbolTable這個詞在傳統編程語言的實現裏頭比較經常使用(This data structure serves many of the purposes of the symbol table of a conventional programming language implementation
),而在jvm裏頭對應的是Runtime Constant Pool中的symbolic references(Runtime Constant Pool除了symbolic references還包含了static constants
),它是在類加載的時候(Resolution in Linking
)根據class元數據中的constant pool table建立的,於是稱爲Runtime Constant Pool;這部分屬於metaspcae,在native memory中
/ # jcmd 1 VM.stringtable 1: StringTable statistics: Number of buckets : 65536 = 524288 bytes, each 8 Number of entries : 23407 = 374512 bytes, each 16 Number of literals : 23407 = 2153344 bytes, avg 91.996 Total footprsize_t : = 3052144 bytes Average bucket size : 0.357 Variance of bucket size : 0.360 Std. dev. of bucket size: 0.600 Maximum bucket size : 5
/ # jcmd 1 VM.symboltable 1: SymbolTable statistics: Number of buckets : 32768 = 262144 bytes, each 8 Number of entries : 128885 = 2062160 bytes, each 16 Number of literals : 128885 = 7160912 bytes, avg 55.560 Total footprsize_t : = 9485216 bytes Average bucket size : 3.933 Variance of bucket size : 3.982 Std. dev. of bucket size: 1.996 Maximum bucket size : 14
SymbolTable statistics: Number of buckets : 32768 = 262144 bytes, each 8 Number of entries : 129215 = 2067440 bytes, each 16 Number of literals : 129215 = 7173248 bytes, avg 55.514 Total footprsize_t : = 9502832 bytes Average bucket size : 3.943 Variance of bucket size : 3.990 Std. dev. of bucket size: 1.998 Maximum bucket size : 14 StringTable statistics: Number of buckets : 65536 = 524288 bytes, each 8 Number of entries : 23470 = 375520 bytes, each 16 Number of literals : 23470 = 2157736 bytes, avg 91.936 Total footprsize_t : = 3057544 bytes Average bucket size : 0.358 Variance of bucket size : 0.361 Std. dev. of bucket size: 0.601 Maximum bucket size : 5
/ # jcmd 1 VM.native_memory scale=MB 1: Native Memory Tracking: Total: reserved=1857MB, committed=112MB - Java Heap (reserved=502MB, committed=32MB) (mmap: reserved=502MB, committed=32MB) - Class (reserved=1065MB, committed=47MB) (classes #8386) ( instance classes #7843, array classes #543) (malloc=1MB #21250) (mmap: reserved=1064MB, committed=45MB) ( Metadata: ) ( reserved=40MB, committed=40MB) ( used=39MB) ( free=1MB) ( waste=0MB =0.00%) ( Class space:) ( reserved=1024MB, committed=6MB) ( used=5MB) ( free=0MB) ( waste=0MB =0.00%) - Thread (reserved=29MB, committed=3MB) (thread #29) (stack: reserved=29MB, committed=2MB) - Code (reserved=243MB, committed=15MB) (malloc=1MB #4744) (mmap: reserved=242MB, committed=14MB) - GC (reserved=2MB, committed=0MB) (mmap: reserved=2MB, committed=0MB) - Internal (reserved=1MB, committed=1MB) (malloc=1MB #2172) - Symbol (reserved=10MB, committed=10MB) (malloc=7MB #223735) (arena=3MB #1) - Native Memory Tracking (reserved=4MB, committed=4MB) (tracking overhead=4MB)
interned String
)及SymbolTablejava7+
),而SymbolTable則在native memory中;使用jcmd pid VM.stringtable能夠在運行時查看StringTable;使用jcmd pid VM.symboltable能夠在運行時查看SymbolTableinterned String
)及non heap中的SymbolTable