JDK-8202951 : Implementation of JEPJDK-8204247: Include default CDS (Class Data Sharing) archive in JDK binary
  • Type: Sub-task
  • Component: hotspot
  • Sub-Component: runtime
  • Affected Version: 11
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2018-05-11
  • Updated: 2021-02-03
  • Resolved: 2018-10-05
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 12
12 b15Fixed
Related Reports
Blocks :  
Blocks :  
Blocks :  
Blocks :  
Blocks :  
Blocks :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Description
Currently, a JDK image includes a classlist generated at build time in lib/ directory. For any users who want to take advantage of CDS even with the default classlist, they need to run -Xshare:dump as an extra step. It would be beneficial to create a default archive (run -Xshare:dump using the generated default classlist) as part of the JDK build and package the archive together with the JDK binary. Thanks to Karen and Alan for initiating the idea.

Benefits of including a default CDS archive in JDK distribution:
- Startup performance improvement (default behavior). With the latest JDK 11 EA build 11-ea+14, using CDS archive improves JVM startup time by 32.59% on linux-x64 with default settings. On other platforms, similar or higher performance gains have been observed with CDS enabled.
- Reduce overhead for users.

Size measurement shows the CDS archive generated from the default classlist is 13% of the lib/modules on linux-x64. Including a default CDS archive will have a small increase for JDK binary footprint.

As the CDS archive contains generated code (CPU specific) although minimum, the packaged archive should be generated on a platform with the same OS and CPU for the target machine.

The impact on testing is large as all test executions will enable CDS by default once a JDK binary is packaged with a default archive. All tiers need to be tested before the proposed change can be integrated.
Comments
Thank Calvin and Erik J. for investigating the proper change for generating default CDS archive. Here is the link to Erik's webrev (copied from JDK-8208351) for makefile changes to create the default CDS archive at JDK build time: http://cr.openjdk.java.net/~erikj/8208351/webrev.01/ As archive cross-generating is not supported, ARM builds will not include default CDS archive: "linux-aarch64-open", "linux-aarch64-open-debug", "linux-aarch64-open-cmp-baseline", "linux-arm32-open", "linux-arm32-open-debug", "linux-arm32-open-cmp-baseline"
14-08-2018

After discussing with GC team and performance team (thanks to Thomas and Claes), we agreed that a smaller java heap size should be used at the default CDS dump time in order to have optimal result at runtime for common use cases. 128M java heap seems to be a good choice when creating the default CDS archive. Just for reference purposes: For java heaps that can be fit within 4G (0x100000000) address space, the heap tops are always at the same address (end at 0x100000000) while the heap bottoms are different depending on the heap size. The narrow oop encoding is 0 based and 0 shift. In most cases, a java heap < 3G can fit within the 4G space. A smaller heap size (as suggested in the above) picked at dump time can help guarantee that. For larger java heaps that cannot be allocated below 0x100000000 but fits the 32G (0x800000000) address space, the heap tops are the same (usually end at 0x7c0000000) while the bottoms are different depending the size. The narrow oop encoding is 0 based and 3 shift.
20-07-2018

For the tier3 failures listed in the mach5 results page: Some failures are the same as in tier1. 2 failures not seen in tier1: serviceability/sa/TestInstanceKlassSize.java stderr: [Exception in thread "main" sun.jvm.hotspot.utilities.AssertionFailure: Invalid bucket id at jdk.hotspot.agent/sun.jvm.hotspot.utilities.Assert.that(Assert.java:32) at jdk.hotspot.agent/sun.jvm.hotspot.utilities.BasicHashtable.bucket(BasicHashtable.java:62) at jdk.hotspot.agent/sun.jvm.hotspot.memory.Dictionary.contains(Dictionary.java:87) at jdk.hotspot.agent/sun.jvm.hotspot.oops.InstanceKlass.isShared(InstanceKlass.java:329) at jdk.hotspot.agent/sun.jvm.hotspot.oops.InstanceKlass.hasStoredFingerprint(InstanceKlass.java:313) at jdk.hotspot.agent/sun.jvm.hotspot.oops.InstanceKlass.getSize(InstanceKlass.java:287) at TestInstanceKlassSize.SAInstanceKlassSize(TestInstanceKlassSize.java:170) at TestInstanceKlassSize.main(TestInstanceKlassSize.java:193) ] serviceability/sa/TestInstanceKlassSizeForInterface.java stderr: [Exception in thread "main" sun.jvm.hotspot.utilities.AssertionFailure: Invalid bucket id at jdk.hotspot.agent/sun.jvm.hotspot.utilities.Assert.that(Assert.java:32) at jdk.hotspot.agent/sun.jvm.hotspot.utilities.BasicHashtable.bucket(BasicHashtable.java:62) at jdk.hotspot.agent/sun.jvm.hotspot.memory.Dictionary.contains(Dictionary.java:87) at jdk.hotspot.agent/sun.jvm.hotspot.oops.InstanceKlass.isShared(InstanceKlass.java:329) at jdk.hotspot.agent/sun.jvm.hotspot.oops.InstanceKlass.hasStoredFingerprint(InstanceKlass.java:313) at jdk.hotspot.agent/sun.jvm.hotspot.oops.InstanceKlass.getSize(InstanceKlass.java:287) at TestInstanceKlassSizeForInterface.SAInstanceKlassSize(TestInstanceKlassSizeForInterface.java:77) at TestInstanceKlassSizeForInterface.main(TestInstanceKlassSizeForInterface.java:174) ]
31-05-2018

For the tier1 failures listed in the mach5 results page: runtime/LoadClass/TestResize.java Existing bug: https://bugs.openjdk.java.net/browse/JDK-8202360 java/util/Map/InPlaceOpsCollisions.java Existing bug: https://bugs.openjdk.java.net/browse/JDK-8203387 runtime/logging/DefaultMethodsTest.java Looks similar to: https://bugs.openjdk.java.net/browse/JDK-8146435 (The above was resolved in JDK9, may need to file another bug) serviceability/sa/ClhsdbSymbol.java Test ERROR java.lang.RuntimeException: 'java/util/HashMap' missing from stdout/stderr serviceability/sa/ClhsdbInspect.java Test ERROR java.lang.RuntimeException: 'Type is Method' missing from stdout/stderr The above 2 seem new issues.
31-05-2018

We have received many complaints that CDS is hard to use, and Java start-up is slow. This RFE is one of the steps that we are taking to address these issues. It *is* customer/user driven. We didn't invent this out of thin air. We want CDS to be used by default. Shipping an archive but disabling -Xshare:auto does not accomplish this. It's a step backward because we force users to specify -Xshare:auto even when they have specified an archive using -XX:SharedArchiveFile=xxx.jsa. This is unnecessary verbosity and makes Java hard to use. So that's not a path that we should take. I agree that this has wide impact. Let's go through a JEP and let the proposal be reviewed by the community.
27-05-2018

As I wrote to Jiangli in email discussion: Turning CDS fully on by default is a significant change in behaviour that should be being driven by higher-level demands from customers/users. It needs to be okay'd by the release team and supported by the Tech leads. And also supported by the community unless Oracle JDK only. If you disable -Xshare:auto by default and supply a default archive then there's no change in behaviour out-of-the-box (except maybe on Windows?). So if you backout the -Xshare:auto change you can also withdraw the CSR request that went with it. [This was in response to a suggestion from Jiangli.] You still need buy-in from other parties that it is okay to include an archive in the build artifacts that get shipped. It adds to build time, adds to disk usage, and potentially disrupts some CDS tests (if they assume no archive exists before the test does a dump). And if we still have an installer on Windows it will need to know about it too.
26-05-2018

[~dholmes] We need to put the risk in perspective. CDS has been enabled (via the win32 installer) on Windows/x86 since JDK 1.5, where -Xshare:auto is default. So people have been using CDS by default for a long time, perhaps without knowing it. For many years, these were the overwhelming majority of users of Java in the most fragile OS environment. Historically the incidents reported by users related to CDS are infrequent, so we have grounds to believe that turning CDS on by default, on all platforms, is low risk. I agree that we need to test thoroughly before making the switch. I think the best way to test this is, in the jdk/jdk repo: + Change the JDK build process to include the default CDS archive in the JDK image. + Use CDS by default for all Oracle internal testing (so we are testing what the user uses). + we should add additional VM flag rotation tests to ensure the VM works well even if user explicitly sets -Xshare:off + All other JDK community members, including major software vendors and distributions, when testing the jdk/jdk repo, will also be testing with CDS-enabled+Xshare:auto, because that's the default now. + All early access users (when this RFE is committed and released in early access) will also be testing this combination I think this will provide sufficient testing to see if there are any side effects, especially if we do this early in a JDK 6-month cadence cycle. I also think this will provide the best coverage (by a vast number of users and platforms) than all other alternatives suggested in previous comments in this RFE. In fact this is how most of the thousands of changesets are tested in each JDK release. Each of these changesets have a non-zero probability of causing failures, but we believe the above testing scheme will properly manage such risks. Since the feature proposed in the RFE, as we believe, does not pose a significantly higher risk, the above testing scheme should be sufficient to ensure its quality.
26-05-2018

On the "why" are we doing this -- CDS has been proven to provide significant start-up improvement. However, historically it's enabled by default only on Windows/x86 because: 1. -Xshare:auto was enabled only in client compiler (see bug JDK-8188105). 2. There was a (misplaced) belief that the CDS archive could be used only on the machine that generated it 3. Only Windows and MacOS had an installer, which were able to generate the archive upon installation. All other platforms we distributed in tarballs. 4. Only the win32/client installer bothered to generate the archive on installation. MacOS did not, perhaps due to neglect, or perhaps because it was using the server compiler. As a result, the benefit of CDS is not available to the user by default, which is really a shame. That's why we are doing this RFE.
26-05-2018

Regarding testing: if we are shipping CDS archive in the JDK distribution, then this should be the default way of running the tests, not the other way around. Otherwise it would be saying we enable G1 by default for the JDK, but somehow G1 is not used by default in regular testing. This doesn't make any sense. If we want to test non-CDS mode, we can just create more VM arg combinations in task-definitions of our tests, to specify -Xshare:off for certain groups of tests. That would be similar to tasks that explicitly set -Xcomp or -XX:+UseParallelGC.
22-05-2018

The archive is only specific to the general CPU family and bit-ness, but not specific to particular sub-architecture features such as SSE, etc.
18-05-2018

[~erikj]Your understanding of the windows installer for CDS archive is the same as mine. Other platforms had no automatic generation of an archive. The proposal in this RFE is to include an archive that's created on the same os-cpu platform that the JDK distribution binary targets for.
15-05-2018

Regarding CDS and windows, AFAIK the windows installer for the Oracle JDK generated an archive at install time. I think this was only done for windows 32bit. I don't know of any other platforms ever having automatic generation of an archive. I thought the archive was too specific to the exact cpu to be practically portable in a distribution. Has that changed?
15-05-2018

[~dholmes]Thank you for the further thoughts! Your suggestion is to creating & packaging the default archive after a normal build process, but do it as an additional step when creating the bundle for download (from openjdk). Yes, that would achieve the same goal as doing it at build time. That's a good solution too!
12-05-2018

[~jiangli]] I understand the potential benefit to the end user who downloads some form of JDK bundle, but I would still argue this should be an additional step done when packaging up that bundle for download (or via the Windows installer for example) - not part of the normal build process that impacts everyone. The storage issue is not concern for the end user but our internal systems that will have to carry around these shared archive files for every build. The testing problem is much more significant: yes CDS will be tested thoroughly, but non-CDS won't be tested at all unless we do special runs that disable CDS!
11-05-2018

One good side effect of this is CDS (including archived java heap objects) would be tested very thoroughly.
11-05-2018

[~dholmes]Thanks a lot for your comments! With this proposal, it creates the default archive at JDK build time. The goal is for immediate benefit. If a user simply unzip a JDK binary on the target machine, the default archive can be used transparently without any additional work. No special installation is required. Storage space probably won't be an big issue because there would be only one default archive packaged within the JDK image. The default archive will be memory shared by all processes running the same JDK binary simultaneously. For testing, because -Xshare:auto is enabled by default, if there is an archive in the default location, the JVM would uses automatically. There would be no -Xshare:dump needed anymore.
11-05-2018

JPRT used to run -Xshare:dump as part of the post-install process for the test binaries.
11-05-2018

This may be useful for the shipped product - doesn't Windows already do that? But for testing this seems very bad - we need to control use of CDS in testing so we'd have to explicitly disable CDS most of the time to ensure non-CDS related class loading works. In addition there are logistical issues with the disk space consumed by the archive. This seems more like a packaging/installer process than part of the main build - that also addresses the "make sure you dump on a compatible platform" problem!
11-05-2018

Given the large impact on testing, this might be doable for JDK 12.
11-05-2018