Issue | Fix Version | Assignee | Priority | Status | Resolution | Resolved In Build |
---|---|---|---|---|---|---|
JDK-8083170 | emb-9 | Jiangli Zhou | P3 | Resolved | Fixed | team |
Currently, every symbol in the SymbolTable is associated with a HashtableEntry<Symbol*, mtSymbol>, which is 24-byte per instance on 64-bit (12 bytes on 32-bit). There is also a 8-byte pointer per bucket slot.
Also, when the SymbolTable is re-balanced, the HashtableEntries may be written into, which would reduce the read-only ratio (even for the HashtableEntry that are placed in the shared archive).
We can use a smaller data structure (8 bytes per symbol) than HashtableEntry, and reduce the size of the buckets to 6 bytes per bucket slot. This is what CLDC does.
// Layout of compact symbol table in the shared archive:
// juint num_symbols;
// juint num_buckets;
// juint buckets[num_buckets];
// jushort bucket_sizes[num_buckets];
// juint table[num_symbols * 2]
//
// Each symbol's entry is 8 bytes in the table[]:
// juint hash;
//#ifdef _LP64
// juint offset; /* Symbol *sym = (Symbol*)(SharedBaseAddress + offset) */
//#else
// Symbol* sym;
//#endif
Currently, with the default classlist in JDK8, on 64-bit JVM, the SymbolTable Hash Entries take up about 6% of total CDS space. After the change, this should go down to about 2%.
Notes:
[1] This means, however, that the SymbolTable now needs to be split into two parts -- the CDS table, which is read-only (and will not be re-balanced), and the "regular" table, which may be modified/rebalanced at run-time.
[2] Shared StringTable (when it's implemented) can be handled in a very similar manner.
Also, when the SymbolTable is re-balanced, the HashtableEntries may be written into, which would reduce the read-only ratio (even for the HashtableEntry that are placed in the shared archive).
We can use a smaller data structure (8 bytes per symbol) than HashtableEntry, and reduce the size of the buckets to 6 bytes per bucket slot. This is what CLDC does.
// Layout of compact symbol table in the shared archive:
// juint num_symbols;
// juint num_buckets;
// juint buckets[num_buckets];
// jushort bucket_sizes[num_buckets];
// juint table[num_symbols * 2]
//
// Each symbol's entry is 8 bytes in the table[]:
// juint hash;
//#ifdef _LP64
// juint offset; /* Symbol *sym = (Symbol*)(SharedBaseAddress + offset) */
//#else
// Symbol* sym;
//#endif
Currently, with the default classlist in JDK8, on 64-bit JVM, the SymbolTable Hash Entries take up about 6% of total CDS space. After the change, this should go down to about 2%.
Notes:
[1] This means, however, that the SymbolTable now needs to be split into two parts -- the CDS table, which is read-only (and will not be re-balanced), and the "regular" table, which may be modified/rebalanced at run-time.
[2] Shared StringTable (when it's implemented) can be handled in a very similar manner.
- backported by
-
JDK-8083170 Compact symbol table layout inside shared archive
-
- Resolved
-
-
JDK-8147990 Compact symbol table layout inside shared archive
-
- Closed
-
- relates to
-
JDK-8071962 The SA code needs to be updated to support Symbol lookup from the shared archive
-
- Resolved
-
-
JDK-8067982 some jcmd /gc/heap_dump tests failed: hprof output contains warning or error
-
- Closed
-
-
JDK-8276662 Scalability bottleneck in SymbolTable::lookup_common()
-
- Resolved
-