Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initialize at build-time a subset of the JDK #2650

Closed
vjovanov opened this issue Jul 3, 2020 · 10 comments
Closed

Initialize at build-time a subset of the JDK #2650

vjovanov opened this issue Jul 3, 2020 · 10 comments
Assignees
Milestone

Comments

@vjovanov
Copy link
Member

vjovanov commented Jul 3, 2020

Currently, the whole JDK is initialized at build time. This causes many issues with packages like java.awt where threads get stored into the image heap.

We plan to minimize the list of packages that are initialized at build time by default. The list should be designed with the following concerns:

  1. It should contain packages that are critical for performance of every-day user programs. All primitives, collections, strings, and similar must be initialized at build time.
  2. It should contain packages that are not hard to maintain (when build-time initialized) and hence cause trouble down the road.
  3. It should not bloat the "Hello, World!" image with many class initializers that will never be executed.

This will unfortunately be a breaking change for many projects. However, this change should bring fewer failures in native images and significantly ease the maintenance of the JDK.

@n1hility
Copy link
Contributor

n1hility commented Jul 6, 2020

Wouldn't it be better to be opt out instead of opt-in? I am concerned about side effects of this (e.g. init time slowdowns, optimizations such as inlining no longer possible, etc). I understand some things like AWT being broken, but Id argue most existing usage of GraalVM today is more server side processing scenarios. It would be a shame to take a step backwards in the 90% use-case for the few outliers.

@fcurts
Copy link

fcurts commented Jul 6, 2020

Is this a breaking change for Truffle languages that use --initialize-at-build-time without qualification?

@sdeleuze
Copy link
Collaborator

sdeleuze commented Jul 7, 2020

👍 for such change.

Could it be possible to change the defaults for JDBC to run time as well in order to avoid JDBC classes to be initialized at build time since that generates some out of the box issues like with MySQL AbandonedConnectionCleanupThread that create threads at class initialization (transitively initialized at build time via java.sql.DriverManager)?

@vjovanov
Copy link
Member Author

vjovanov commented Jul 8, 2020 via email

@vjovanov
Copy link
Member Author

vjovanov commented Jul 8, 2020 via email

@vjovanov
Copy link
Member Author

vjovanov commented Jul 8, 2020

@sdeleuze java.sql is now initialized at run time. I don't know about the implementations of the drivers for the various databases. If someone, has --initialize-at-build-time, they should manage that themselves.

@Sanne
Copy link
Contributor

Sanne commented Jul 19, 2020

@n1hility I have investigated the changes to class initialization and for most applications the changes are minimal. For example, the “Hello, World!” adds only 3 classes to initialization at run time, and those are never executed. Once I am done I will post some numbers to show the difference. Now, even if we do make a mistake, we can always initialize something at build-time again (it is not a breaking change). However, this time it will be an informed and thoroughly tested decision.

@vjovanov I see this was closed now. Could you share some more details? Do you have some of those numbers backing the decision?

Regarding JDBC, I don't see the problem: it's all working fine in Quarkus.

@vjovanov
Copy link
Member Author

@Sanne Yes we had to merge it before the branching for 20.2. The performance numbers on all the benchmarks we have are completely unchanged. The image sizes have changed on some benchmarks though:

image

We will have to investigate where does this comes from and try to fix it. This time, however, when something is initialized at build time it will have to pass all the Java tests on all supported platforms.

@Sanne
Copy link
Contributor

Sanne commented Jul 20, 2020

many thanks @vjovanov !

Speaking of tracking down large inclusions; I have to admit that it's been a couple of years since I explored such aspects; we did some in the early Quarkus prototypes mostly as an exercise to learn about the GraalVM optimisations, using a debugger and the huge call tree text reports which native-image can produce.

Is there a better way now to track down why some code path was included, or assert during testing that something will not be included?

I think that if there was a better way, we could help a bit more on polishing such aspects; some people aren't satisfied yet with the sizes (personally I'm just being curious).

@vjovanov
Copy link
Member Author

Unfortunately, there is still no official tool for doing this so we have to use the good old log analysis here. We need to approach image size from all angles: 1) change the JDK where possible to avoid pulling in unnecessary stuff, 2) initialize at build time code that pulls unnecessary stuff, 3) improve analysis, and 4) do specific compiler phases to reduce code size.

I believe the only way to make it great is to tackle all four problems at the same time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants