последовательность
В этой статье в основном рассматриваются StringTable и SymbolTable jvm.
StringTable и SymbolTable
JDK изменения
В java7 пул строковых констант был перемещен в кучу java, а пул строковых констант был ограничен памятью кучи всего приложения.Вызов String.intern() во время выполнения для увеличения строковой константы не приведет к постоянному созданию ООМ. Используйте -XX:StringTableSize для установки StringTableSize, по умолчанию 65536
В java8 PermGen был удален, а область метода была перемещена в метапространство вне кучи, поэтому SymbolTable также была перемещена в некучу с помощью метапространства.
SymbolTable
symbolic references in Runtime Constant Pool
- Полный процесс загрузки класса должен проходить через загрузку (
Loading
),соединять(Linking
), инициализация(Initialization
) эти три шага - На этапе загрузки класса загрузчик класса отвечает за чтение двоичного потока байтов класса в JVM в соответствии с полным именем класса, а затем преобразование его в экземпляр объекта java.lang.Class, соответствующий целевому объекту. type; Что делает фаза подключения, так это объединяет информацию о классе двоичного потока байтов, загруженного в JVM, в состояние выполнения JVM после проверки (
Verification
),Подготовить(Preparation
), разбор (Resolution
) три этапа; этап инициализации выполняет весь код, идентифицированный ключевым словом static в классе, единообразно. Если выполнение является статической переменной, начальное значение, установленное на этапе подготовки, будет перезаписано значением, указанным пользователем; если выполнение представляет собой статический блок кода, то на этапе инициализации JVM выполнит все операции, определенные в блоке статического кода. - в связи (
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 (Runtime Constant Pool除了symbolic references还包含了static constants
), который выполняется при загрузке класса (Resolution in Linking
) создается в соответствии с таблицей пула констант в метаданных класса, поэтому он называется Runtime Constant Pool, эта часть относится к metaspcae, в родной памяти
Просмотр таблицы строк
/ # 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 pid VM.stringtable для просмотра во время выполнения.
ViewSymbolTable
/ # 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
- Используйте jcmd pid VM.symboltable для просмотра во время выполнения.
Просмотр StringTable и SymbolTable
-XX:+PrintStringTableStatistics
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
- Добавьте параметр -XX:+PrintStringTableStatistics при запуске и выводите статистику SymbolTable и StringTable при выходе из процесса jvm.
jcmd pid VM.native_memory
/ # 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)
- Раздел символов вывода с использованием jcmd pid VM.native_memory содержит StringTable(
interned String
) и Таблица символов
резюме
- В java7 пул строковых констант перемещается в кучу java, а пул строковых констант ограничен памятью кучи всего приложения.Вызов String.intern() во время выполнения для увеличения строковой константы не приведет к постоянному созданию ООМ. Используйте -XX:StringTableSize, чтобы установить StringTableSize, по умолчанию 65536; в java8 удалите PermGen и переместите область метода в метапространство в не-куче, поэтому SymbolTable также перемещается в не-кучу с метапространством
- StringTable находится в куче (
java7+
), пока SymbolTable находится в собственной памяти; используйте jcmd pid VM.stringtable для просмотра StringTable во время выполнения; используйте jcmd pid VM.symboltable для просмотра SymbolTable во время выполнения - Добавьте параметр -XX:+PrintStringTableStatistics при запуске и выводите статистику SymbolTable и статистику StringTable при выходе из процесса jvm; часть Symbol, выводимая jcmd pid VM.native_memory, включает StringTable в куче (
interned String
) и SymbolTable не в куче
doc
- Механизм загрузки классов Java
- Chapter 5. Loading, Linking, and Initializing
- 5.1. The Run-Time Constant Pool
- Understanding String Table Size in HotSpot
- Разговор о PermGen и Metaspace jvm
- Will Java's interned strings be GCed?
- Garbage collection behaviour for String.intern()
- 10 Things Every Java Programmer Should Know about String
- Difference between String literal and New String object in Java
- Understand JVM Loading, JVM Linking, and JVM Initialization