JDK-8251330 : Reorder CDS archived heap to speed up relocation
  • Type: Enhancement
  • Component: hotspot
  • Sub-Component: runtime
  • Affected Version: 16
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2020-08-10
  • Updated: 2024-04-17
  • Resolved: 2024-03-13
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 23
23 b14Fixed
Related Reports
Duplicate :  
Relates :  
Relates :  
Relates :  
Relates :  
Description
Many of the objects in the CDS archive heap have no non-null oop fields. (E.g., type arrays, or an object whose oop fields are all null). 

With the attached patch, we can see that more than 60% of the spaces used by the archived heap don't need to be marked by the oopmap.

We should reorder the archived heap to segregate the objects that don't need marking. This will save space in the archive and improve start-up time (see also JDK-8251322)

calculate_oopmap: objects =  15262 (507904 bytes, 332752 bytes don't need marking), embedded oops =    8408, nulls = 54
Oopmap = 15872 bytes

calculate_oopmap: objects =  4590 (335872 bytes, 178120 bytes don't need marking), embedded oops =   46487, nulls = 29019
Oopmap = 10496 bytes

(332752 + 178120) / (507904 + 335872.0)  = 0.6054592688106796


Comments
Changeset: 7e05a703 Author: Matias Saavedra Silva <matsaave@openjdk.org> Date: 2024-03-13 14:00:59 +0000 URL: https://git.openjdk.org/jdk/commit/7e05a70301796288cb3bcc6be8fb619b6ce600bc
13-03-2024

A pull request was submitted for review. URL: https://git.openjdk.org/jdk/pull/17350 Date: 2024-01-10 17:19:39 +0000
22-02-2024

Prototype: https://github.com/openjdk/jdk/compare/master...iklam:jdk:8251330-reorder-archive-heap-for-fast-relocation.20231102?expand=1 The archived heap objects are sorted like this: - objects that have no pointers - objects that have only native pointers - objects that have both native and oop pointers - objects that have only oop pointers "java -Xshare:dump -Xlog:cds" shows [3.596s][info ][cds] Size of heap region = 1084456 bytes, 24391 objects, 2331 roots, 1624 native ptrs [3.632s][info ][cds] oopmap = 143286 ... 271114 ( 52% ... 100% = 47%) [3.632s][info ][cds] ptrmap = 50713 ... 74183 ( 37% ... 54% = 17%) So the oopmap now covers only 52% of the objects, and the ptrmap covers only 17% The size of the bitmap region (which holds both oopmap and ptrmap) is reduced: Before: Shared file region (bm) 2: 263048 bytes, addr 0x0000000000000000 file offset 0x00d3f000 crc 0x3774252c After: Shared file region (bm) 2: 260128 bytes, addr 0x0000000000000000 file offset 0x00d3f000 crc 0x8b86ade2 ptrmap size is reduced in ArchivePtrMarker::compact(), by removing all the zero bits at the end of the bitmap. TODO: We need remove the leading zeros from oopmap and ptrmap: $ java -Xshare:dump -Xlog:cds+map | grep lead [3.777s][info][cds,map] - heap_oopmap_leading_zeros: 143286 [3.777s][info][cds,map] - heap_ptrmap_leading_zeros: 50713 So we can reduce the "bm" region by (143286 + 50713) / 8 = 24249 bytes.
02-11-2023

This RFE will also help JDK-8310823 to use a more optimized relocation algorithm.
10-07-2023

Estimate of benefit: First, find the heap size that would trigger heap relocation. This is different on each machine/os: # This is the heap size used for the default CDS image (see make/Images.gmk) $ bin/java -Xmx128m -Xms128M -Xshare:dump $ bin/java -Xlog:cds -Xmx2040m -version 2>&1 | grep 'CDS heap data need to be relocated' $ bin/java -Xlog:cds -Xmx2050m -version 2>&1 | grep 'CDS heap data need to be relocated' [0.009s][info][cds] CDS heap data need to be relocated because the archive was created with an incompatible oop encoding mode. [0.009s][info][cds] CDS heap data need to be relocated lower by a further 1048576 bytes to 30063722496 to be aligned with HeapRegion::GrainBytes Then, measure the time difference with/without heap relocation (Before JDK-8244778) $ perf stat -r 200 bin/java -Xint -Xmx2040M -Xms128m -version 59,499,329 instructions # 0.62 insns per cycle 0.035823700 seconds time elapsed ( +- 0.36% ) $ perf stat -r 200 bin/java -Xint -Xmx2050M -Xms128m -version 59,714,599 instructions # 0.62 insns per cycle 0.036047915 seconds time elapsed ( +- 0.35% ) So the delta is about 210,000 instructions. Reordering will give no more than 60% improvement (see numbers in the Description), so the proposed optimization will probably yield a saving of less than 100,000 instructions. (After JDK-8244778, where the archived heap has become bigger) $ perf stat -r 200 bin/java -Xint -Xmx2040M -Xms128m -version 38,902,409 instructions # 0.60 insns per cycle 0.024895394 seconds time elapsed ( +- 0.37% ) $ perf stat -r 200 bin/java -Xint -Xmx2050M -Xms128m -version 39,228,854 instructions # 0.59 insns per cycle 0.025351305 seconds time elapsed ( +- 0.36% ) The delta is now about 330,000 instructions. The estimated saving is still small.
02-09-2020