Hacker News new | comments | show | ask | jobs | submit login
JEP 295: Ahead-of-Time Compilation (java.net)
220 points by yarapavan on Oct 27, 2016 | hide | past | web | favorite | 142 comments

Seeing as nobody is reading the fine text

* Only 64bit Linux on AMD64 is supported, so no ARM or Android support currently.

* Files must be ran on computers they were compiled on, or identical hardware

* Still needs GC, only G1 and Parallel GC are supported

* No dynamic byte code (Lambda Expressions, Dynamic Classes, etc.)

* The only supported module is java.base

* No decrease to JVM start up times

* Still need the JVM

* Some decrease to spin up as there will be less JIT passes that require stopping the world.

Effectively this just lets you pre-load .class files into the codecache directly rather then running the ~10k initial byte-code passes before they'd receive a JIT pass and that would happen.

Lastly .so is just used as a container so I doubt we can expect to dynamically link against AOT compiled Java in C/C++/Rust land.

> No dynamic byte code (Lambda Expressions, Dynamic Classes, etc.)

That just means it won't be AOT compiled. The JVM can still JIT them.

> No decrease to JVM start up times

The JVM itself starts quite fast. Most of the time spent in startup comes from the applications themselves. Spend a lot of time in the interpreter running their startup code and burning CPU cycles on the lower compiler tiers.

> The only supported module is java.base

Supported in the sense of oracle offering support. You can still compile other modules. It's just experimental.

> The JVM itself starts quite fast. Most of the time spent in startup comes from the applications themselves.

Jar unpacking can contribute quite a bit to startup times. It would be neat if this also did a pre-linked library as well.

An optional link step at build time is coming in Java 9. http://openjdk.java.net/jeps/282

So if you use .class files instead of .jar files, you'll start up significantly quicker?

Yes. In fact many systems unpack jars to a temporary directory first for this reason.

edit: I should add that this really only matters for large numbers and sizes of jars.

"Non-tiered AOT compiled code behaves similarly to statically compiled C++ code, in that no profiling information is collected and no JIT recompilations will happen."

My question is how much memory can be saved by not having the JIT. Sure you still have a GC with a heap (VM) but one of the big pigs in memory can be the JIT.

This is an interesting question. The JVM CodeCache is normally rather small 24MB-48MB. But the JIT and all of its IR/Branch tracking? I Imagine non-trivial.

wait. since when is 24-48MB trivial?

I would have hoped to see it sub 5MB.

Since we have significantly more RAM to spare than a few years ago and caching, almost by definition, is nothing but trading memory for cpu cycles. You want less memory? No problem, just remove the cache and recompute everything all the time, but don't cry if it takes time.

If 24-48MB is trivial completely depends on what is stored in this space, i.e. is there a more efficient representation for your stated goals? Context is king. Even 5MB could be non-trivial, depending on context.

Since Java.

Java can run in a few hundred KB, and is actually used a lot by electronic manufacturers.

There are quite a few manufacturers that have been replacing their firmware with such versions of Java.

How may I get this JVM you speak of?

    $ java -version
    openjdk version "1.8.0_91"
    OpenJDK Runtime Environment (build 1.8.0_91-8u91-b14-0ubuntu4~14.04-b14)
    OpenJDK 64-Bit Server VM (build 25.91-b14, mixed mode)

    $ java -Xmx999k
    Error occurred during initialization of VM
    Too small initial heap

Ahah,what about using an actual JVM for embedded hardware, instead of trolling?

If you don't know better I can gladly provide you some links to embedded Java vendors.

My point was that Java uses a lot of memory and < 5MB for code cache was an unrealistic expectation.

I welcome concrete counterexamples of why this expectation would be realistic.

Aonix PERC Ultra and Pico are into a few KB. Sorry documentation is no longer available since PTC bought Aonix


JamaicaVM requires 1 MB


MicroEJ can target Cortex-M processors with 128 KB flash and 32 KB RAM.


Oracle's offerings, Java ME Embedded reference implementation requires 128 KB RAM and 1 MB ROM


Java ME might not seem relevant in 2016, but it is running on the majority of Ricoh copiers


And smart devices produced by Gemalto like Cinterion, EHS6 digital phone or smart meters.



Cisco phones,


And many other embedded manufactures, that are jumping into IoT.

Rather since we have multi-gig RAM on consumer machines.

On embedded systems it might not be trivial, but on my laptop with its 4gigs of RAM and even more so on my desktop with 16gigs, 50mbs is definitely trivial.

> Only 64bit Linux on AMD64 is supported, so no ARM or Android support currently.

Do you know what you are talking about ? Android is totally different thing than JVM and Java Ecosystem ! It is totally different technology ! They use one step to turn your bytecode to their own dex file, after that it is completely separated from Java ecosystem (Java as ecosystem which comes from Oracle).

I am fascinated on HN, how comment uneducated like this, haven't got down voted.

They use kind of hybrid AOT/JIT right now. (It was interpreter until 2.2, they switched to JIT, in android 5 they switched to complete AOT, now they are going kinda hybrid approach).

This is clearly still great for a few places. For example in the trading industry, you would have a few seconds of being very slow when starting up for the week - or anytime you crashed and needed to reboot midweek.

Also risk of "hot pathing" the wrong paths if the server comes up during say a market closed time...

I'm surprised to hear anyone running Java in the trading industry. Isn't speed a huge factor in that industry?

> Isn't speed a huge factor in that industry?

Exactly. There are a lot of high performance system written in Java. For long running systems, the startup cost is irrelevant. And for networked systems (such as fintech) you are going to be IO bound. The main issue as far as Java and high performance is the GC related pauses and that is a concern shared with any GC'd runtime.

And for Java it's actually much less of an issue thanks to the crazy manhours put into developing fast GC for Java. I suspect Azul Systems's pauseless GC is probably quite popular in HFT.

They are trying to sell it for sure. They attend a lot of events.

I am not aware of any trading company using it. May be some.. but the high perf people I know go other ways.

The JVM is super speedy, if you can mitigate startup time and the time required to warm up the JIT.

... and Distruptor/Aeron. (etc.)

You're assuming Java is slow. Evidence suggests otherwise. Eg. LMAX Exchange uses a lock-free ringbuffer they call Disruptor [1] which enables 6M tps on a single thread [2]

[1] https://lmax-exchange.github.io/disruptor/ [2] http://martinfowler.com/articles/lmax.html

And disruptor is a few years old now, there is a whole new wave of queues with even better performance.

I seem to recall a prior discussion where a dev working on HFT stuff said that speed is a huge factor, but so is the ability to rapidly change functionality. They settled on Java because it was fast enough (HFT would have to be IO bound, right?) while still being flexible enough to allow them to adapt to daily changes in requirements.

Besides what the others already replied, the use in the trade industry is one of the reasons of Java having to adopt AOT, value types, JNI replacement and better integration with GPGPUs.

Thus the Java.

Java shot itself in the foot with the whole GC thing. Then it built a gigantic robot exoskeleton called Hotspot to help itself walk fast again.

Java's GC isn't why it can be slower than C/C++ and the JIT (HotSpot) has nothing to do with the GC.

Well you just told that to someone who lived with GC pauses and profilers for years. And I did not say hotspot is about GC.

A lot of firms will run some training data through their application after startup, so that the hot paths get optimised.

I have done this so can confirm, but every time I did I wished I didn't need to. I had a running nightmare where yesterday's trading data made us trade today.

Or today's trading is different enough from yesterday's that your app hits perf issues. Black swan, anyone?

Might not even be that. At some point you need to cut out the output from going to the real exchange.

If you had an IF somewhere random in your code.. you will then JIT code that is wrongly optimized.

If you try to put some kind of network device to capture the traffic and respond with fake responses to make the code happy.. you are one bitflip away from sending bad stuff to prod.

> you are one bitflip away from sending bad stuff to prod.

Including some ascii art of Trogdor the Burnanator!

Ya that is tricky with binary formats. What exchanges still support ASCII? I want to send messages that are both ASCII art and a valid trade...

Except at the exchange, where you can't do this. Or you accidentally bitflip something and take yesterdays data, inject into todays books, and cause millions of dollars in mistakes.

Those savings might still be beneficial. For instance this might be a decent speed up for GC Functions / AWS Lambda

This sounds like it is just a modern gcj, then. Am I reading it wrong?

The "just" part doesn't make a lot of sense but otherwise it's a fair characterization

Sorry, if you are reading it as "no big accomplishment", yeah, not right.

My question is really "why will it succeed this time?" Did GCJ and similar technologies not take off because Sun didn't support them? Or because it is a really neat technical challenge that solves a problem people don't actually care about?

So, yes, this is cool. But, I'm currently giving it a likelihood of success really low, since I have priors that failed. What other evidence are people seeing that make this something to be excited about, as opposed to just impressed. (Or, are we just impressed and I can go back to my corner?)

Almost all commercial JDKs support AOT to native code.

Sun was religious against it.

Regarding the GCJ, it failed because it is a hard problem where people didn't work for free and most of them stopped working on it when the OpenJDK was released.

Do you know if any commercial JDKs release any metrics on the use of this?

Unfortunately no, I am aware of them, because as language geek I like to research these subjects.

While others read newspapers on the train, I read papers. :)

In any case, these provide AOT.

JamaicaVM, PTC Perc (former Atego and Aonix), IBM J9, Oracle Embedded Java, OS/400 Java (uses the same bytecode deployment as the other OS/400 languages), Excelsior JET, and probably a few others in embedded market that I am not aware of.

And of course the Android Java fork with ART.

Awesome, thanks for responding. I have the same hobby of reading up on this sort of stuff, so I knew of quite a few of those. Just don't know of much for a use case of them.

I think the big distinguishing feature is that this is first-class support built into the platform, so it will likely have many more users than previous efforts. I don't anticipate it being generally useful until at least JDK11, though.

I had thought Sun did back one of the early methods of compiling to native. (Pretty sure my memory is just wrong.)

Sun only supported it on bare metal embedded scenarios, they were religiously against it.

Can you statically compile executables? That's a huge win right there.

The great language convergence is happening! It seems like everyone is moving to expressive statically typed, compiled, functional, oop languages. Not that I'm complaining.

This means that we might actually get a language that becomes the new c in terms of popularity.

I look at this as cyclic trends (I'm not sure if 'trend' is the right word here, but it's a good enough approximation) - as you've said, we're entering the cycle of 'expressive statically typed, compiled, functional' (not sure about oop), but soon the cycle will go back to the dynamic languages, because they are "faster when iterating on product" etc. But who knows, maybe we'll stay in current cycle forever? ;)

I don't think so, well, at least not entirely. :-)

Dynamic languages were attractive as an alternative to being forced to specify types all the time, even when it's "obvious." Nobody would have complained if type errors were pointed out for "free."

But type inference is getting popular (eg scala), which is showing people that you can have your cake and eat most of it too.

There's also a lot of little things like REPLs, runtime metaprogramming, blah blah, that used to be solely the domain of dynamic languages, but popular interpreters/VMs have gotten way better in the last decade or two (thanks, JVM) and shown that you actually _can_ have it all. There's no longer a big strong line between interpreted and compiled.

If you can make a statically typed language expressive and fast-to-iterate enough, which I think you can and we (mostly) have, then that kind of yanks the ground right out from under the feet of the dynamic languages, leaving them with no real reason to exist in the long run.

That said, there's something attractive to the unexperienced about being able to code in the laziest possible way, and I don't think platforms that deliver a tiny bit of value in the short run in exchange for massive payback in the long run will ever lose popularity, among new engineers who have not yet learned what it's like to maintain a large program. There will always be PHPs as long as there are students. And that's OK. You learn to do thing well by doing things poorly. But hopefully over time such tools will mainly be used for trivial and learning projects, not big mission critical things

> There's also a lot of little things like REPLs, runtime metaprogramming, blah blah, that used to be solely the domain of dynamic languages

If you go read the Xerox PARC, DEC and ETHZ papers you will find REPL goodies using static system programming languages with automatic memory management.

The Xerox ones even did correction suggestions when compiler errors happened.

Namely Mesa/Cedar, Modula-2+, Modula-3, Oberon and its descendants.

Swift, Java, Scala, Haskell, Etc all have REPLs as well.

Yeah, I was just trying to point out that it isn't something recent, rather all the way back to early 80's.

For example Oberon System 3 already had something in spirit similar to Swit Playgrounds.

I honestly hope you are right :)

I've been thinking about type inference in this context but I don't think that's enough to convert people to static languages. I agree that there is a general problem with the 'laziest possible way' to program as you put it - dynamic languages are way more forgiving that static ones. And while tools may evolve to make some things trivial, I think that there (almost) always be some areas where dynamic languages' forgiveness will be good enough reason for some people to use them. Today these are types but in the future there'll be something else to sacrifice.

Just as a little addendum to that:

The theory of statically typed languages[1] is progressing while "dynamic" languages haven't actually had many real advances since e.g. Scheme[0] first appeared. Sure, there's small things around ergonomics, immutability (Clojure, especially), but really there's been very little true advancement[2].

Personally, I think either static (dependent) types will win[3] or we'll just end up implementing different custom static type systems ad-hoc[4]. My reason for having more confidence in the former rather than even more formal methods is that there are very few math-like/truly spec-level languages (e.g. TLA+) that can be mechanically translated to a meaningful program. We need something intermediate, but so far (to me!) Idris[5] has seemed like the only remotely credible contender in that you can pretty much choose arbitrarily how much provin' vs. how much assumin' you want to do.

EDIT: The current hype (in frontend especially) seems to be around 'gradually typed' languages like TS and Flow, but AFAICT they are basically just a very poor man's ad-hoc version of dependently typed languages. (Concretely TS/Flow do have a huge advantages in that it's really easy to introduce, but personally I had no problem transitioning gradually from ES6/traceur to Scala.Js/React just by adding strongly typed shims where appropriate. If your application is so tangled that you cannot introduce such shims in various places, it's probably tangled enough that you'll want to do a full rewrite anyway.)

[0] I think Scheme was the first to introduce first-class continuations. That was a pretty major advance in terms of expressing, for example, search algorithms by just rewinding to a previous continuation. Of course, since then "we"(Felleisen, specifically) discovered that delimited continuations are perhaps better -- but that was a 'refinement'.

[1] Aka: languages with more than one type.

[2] Of course, some might interpret (pun!) that as a sign that they're "perfect". However, we still get loads of bugs in dynamically typed languages, so surely there must be something to be improved upon, right?

[3] See e.g. "State Machines All The Way Down" at https://eb.host.cs.st-andrews.ac.uk/drafts/states-all-the-wa... (DRAFT)

[4] See e.g. "Type systems as macros" at http://www.ccs.neu.edu/home/stchang/pubs/ckg-popl2017.pdf (DRAFT)

[5] Since I'm already thowing around references, I'd also point to the "Elaborator Reflection" paper; PDF at http://davidchristiansen.dk/drafts/elab-reflection-draft.pdf ; video at https://www.youtube.com/watch?v=pqFgYCdiYz4 . It shows just how much provin' you can do with just a little bit of ad-hocness at compile time.

I don't really see the cycle. I just see it as languages getting closer and closer to Lisp, as per usual. Turns out the static languages had a lot more growing up to do than the dynamic languages, so you're seeing 'big' changes like Java 7 through 9, C++0x through C++1y, new languages like Go, Rust, Nim, Scala... Meanwhile the only recent dynamic languages worth talking about are Clojure, and maybe Julia and Elixir. Across the field of dynamic languages though you see a little more movement to optional typing (and more powerful typing semantics like schema or protocol conformance or other things you can do with dependent types) and maybe some concurrency or JIT or AOT trinkets from other implementations that all boil down to performance improvements of some sort. The language design on the dynamic end has changed much less because they have less to change.

Yeah it's an extinction event in the evolutionary cycle of computing. Im not sure when was the last one.

I think that excessive dynamism is getting less attractive when you account for all the costs it brings with it and that the vast majority of the benefits can be achieved with static metaprogramming, in a more readable and safer manner.

When we lost type safety in systems programming to C and C++.

So, everything is slowly converging on Scala? (Though of course none will reach the asymptote that is Scala's feature count.)

Or, hopefully, the asymptote that is Scala's compile times.

    functional, oop
Do these have any intersection except Scala?

Depends on how exactly how functional you want to go, but latest versions of C++, Java, JavaScript, and C# definitely qualify. Rust, too, though it's not strictly OO. And Python, Ruby, Swift.

If Rust is OO then the term is meaningless. No inheritance; dynamic dispatch only via explicit indirection (Boxed traits); methods are (therefore) just syntactic sugar for regular functions.

Lisp CLOS does not have inheritance for methods either, but is OO by definition.

Imho, OO is about polymorphism [0] and Rust provides that.

[0] http://beza1e1.tuxen.de/articles/oop.html

Common Lisp has inheritance of methods, but it does not work on a class hierarchy directly. When a generic function gets called, the applicable methods are being ordered based on the classes of the arguments - not just one argument, but possibly many. A more specific method can call the next method. In some cases this is done automatically. This is inheritance, based on the class hierarchy.

CLOS also allows the developer to implement other inheritance mechanisms, by developing his own way to combine the methods of a generic function.

Rust fails many of the other tests mentioned. As for polymorphism, is Haskell OO? If so, then I think my claim that the term is meaningless is justified.

This is the punch line. Once you have a definition of OO, which fits all languages usually considered OO, the definition also fits Haskell. :)

CLOS effectively does have inheritance for methods because for sane specializers subclass matches everywhere where it's superclass matches. One can in fact view the CLOS mechanism of specializers and effective-method composition as more flexible mechanism for inheritance than traditional implementations of OOP.

I disagree; with encapsulation, polymorphism, and composition, Rust seems OO enough to not make the term "meaningless".

At least, not according to the widely used definitions I've read of OO.

All of these things are found in Haskell as well; it's not OO by any stretch of the imagination. You're confusing "oop language" with "modern programming language".

If Rust is FP then that term is meaningless too ;-)

Does OCaml counts ? the OO layer is actually pretty interesting.

It's funny, OCaml's object system is actually quite good, but it doesn't really get used much because, well, why use objects when you have ML?

Yes that's a nice Cobra Effect.

And don't forget Erlang as well.

OCaml, which is now 20 years old. The "O" was originally for "Objective".


For the JVM experts here: how realistic is it for OpenJDK developers to add a command line "-useGreenThreads" option? In Golang, you can create thousands and thousands of threads and there's no issue. If I tried that in the JVM, it would quickly crash. But if there was a "-useGreenThreads" option, I could create Java Executor threadpool of size 50000, use existing http client libraries, and get full concurrency.

Quasar might be the closest in the meantime. One problem is that blocking IO blocks all the green threads (fibers). It might be possible for Oracle or someone to fix that by wrapping NIO with green threads to implement the IO APIs. Most people will just use async NIO wrapped in fibers so it appears synchronous. Also with Quasar any calls to Thread sleep, wait, or synchronization block all the threads. It would not be an easy feature for Oracle to add but Quasar has been attempting to get merged into the JRE. For Java 9 they said they got some features added that improves the situation but Quasar instrumentation will still be required.

The Quasar instrumentation in my opinion is a pain. Out of the box you either get AoT instrumentation or you use Java agent command line option. Both were problematic for me in context of build processes, IDE support, etc. It's possible to do runtime instrumentation with no special command line option using the Quasar URL classloader and Ant task which scans classes to instrument.

> I could create Java Executor threadpool of size 50000, use existing http client libraries, and get full concurrency.

No, you'd get a slow illusion of full concurrency. The JDK ditched green threads ages ago because native threads were far more robust.

I probably shouldn't have used the term "green threads" since that has history in the JVM. I meant whatever Golang is doing which is similar (M:N threading). With an AOT option for Java, this becomes even more of an option. Golang has shown this works, why can't Java implement the same idea and let all existing libraries benefit from it?

Green Threading is M:N threading. Go-Routines are M:N threading. Q.E.D. M:N threading isn't a new idea. Go just offers a backed (or compiled) in run-time that does M:N threading by default for you.

While nearly every other Green Threaded language offered as an additional library/option. This hurt adoption. While Go just forces you to use Green Threading.

    With an AOT option for Java, this becomes even more of an option.
Not in the slightest.

     why can't Java implement the same idea and
     let all existing libraries benefit from it?
A laundry list of reason:

1. Change what functions do and don't block can cause huge issues with down stream libraries/people who depend on system libraries behaving the same thing tomorrow as they did yesterday.

2. Refactoring all code around system calls so they never block.

3. Write a multi-core and multi-socket scheduler.

4. Write a scheduler to balance multi-core and multi-socket thread load.

5. Determine how you will do polling, and write a polling strategy to figure out what green threads are/are not blocked, then figure out how to communicate this information efficiently.

6. Repeat the above 5 steps for EVERY platform Java runs on.

Well, it was a runtime option that was requested, and runtime options don't have to be identical on every platform.

Actually they do. That is the entire point of Java.

No, the point was to make compile-once run-anywhere software. It's natural for tuning runtime parameters to vary.

The hotspot JVM will accept both -d32 (32-bit data model) and -d64 (64-bit data model) everywhere, but they will only work on certain platforms.

Robust, sure, but they offer an interface far too heavyweight for simple tasks.

The interface is exactly the same as green threads. It is the implementation that is far more heavy than green threads.

The first wave of JVMs had it, but they eventually dropped because it wasn't worthwhile for the type of Java workloads.

The language specification doesn't state anything about how threads should be scheduled.

There are actually a few embedded JVMs that might still offer it.

There are problems with separating JVM and OS threads, mostly in assumptions that native library authors may have made about that mapping being 1:1. That isn't to say the situation can't be improved in specialised environments (see the JVM at Google talk at http://www.oracle.com/technetwork/java/javase/community/jlss...) but fixing it in general is a hard problem. It is being thought about though - see John Rose's talk at this year's JVMLS.

Thanks for the replies, I think I understand better now why this isn't as possible as I hoped.

Not sure why I'm getting downvotes for just asking a question, I thought this place was about discussion of ideas.

Why do you need a JVM flag for this? There are libraries that do it.


Because that's at the library level. It would require rewriting code to use it which loses one of the big advantages of the JVM (a huge existing ecosystem).

If it's at the JVM level (with a command line option to change how threading is done such as -useGreenThreads") then it's transparent to all existing code. I can just use anything (such as existing JDBC library), increase threadpool to levels that would be considered "ridiculous" with current JVM threading system, and it would all work fine. No code changes necessary for existing libraries.

Except I don't think you can just magically do that.

People do this in Python, but they do it in Python because

1) Python is dumb and has the GIL, much easier to hack in

2) They use reflection to change libraries, but it breaks anytime you would hit native C code. With Java trying to JIT everything, you are now having to change threading at the assembly level.

I think it is would be a ton of work to do at the base JVM level. If you look at the people behind the library I linked, it is many of the core Java people. They might have more insight on reasons why it won't work.

Green threads are very different from system threads. With green threads you get an illusion of concurrency, and when coding you need to account that multiple green threads work on a single system thread.

There's no way you would get a switch like that, because you interact with them differently. I wish greenthreads would not use "thread" in the name because it causes confusion like in your case.

Green threads and system threads are the same illusion to programmers (or, at least, they can be). The only caveat is that dependencies using system threads won't play nicely with green threaded code. Quasar, which does green threads for Java, schedules and distributes your green threads to system threads, one for each cpu. The Quasar API for green threads is basically identical to built in Java APIs.

How is the concurrency illusionary?

Well a System with 16 CORE / 32 Hardware threads.. you run a program with 32 threads, you can legit run 32 things in parallel. Now not really because of OS scheduling and logs and other junk going on, but it could actually happen.

You take the same code and run it with 3000000 green threads... you are still capped out at 32 things running at the same time. Your system can kinda sorta pretend to be more concurrent, but the actually concurrency is the same.

Yeah, but you could also have thousands of system (OS) threads in that same hardware, and they wouldn't run at the same time either.

(Also, they're still concurrent, just not parallel: https://vimeo.com/49718712)

This is very exciting, but still a long way from what people probably think it is at first glance.

This isn't "compile your application to an EXE", like Go or Rust. This is "compile some or all of your application to a DLL, and then have the Java runtime use that DLL".

In other words, you still need a JRE available. The use case for this is simply optimizing hotspots in some very specialized situations.

Not even compile to a DLL, really. The file format happens to be an ELF shared object, but its contents are unusable to anything other than Java, so it's effectively just a blob.

Anyone willing to pay for them, can buy a commercial AOT compiler for Java today, there are quite a few available.

This is significant for those that want to AOT Java without paying for it.

Some info for those that want to AOT Java without paying for it:

The entry-level edition of Excelsior JET is free (as in beer) since the end of August 2016. Licenses for the more senior editions have been available for non-commercial use at no cost for many years.


Hotspots aren't really going to be any faster with this change. The jvm already does a pretty good job of optimising hot code, which is why the vm is literally called hotspot.

AOT compilation is mostly intended to address startup time, Java has a big std library and much of it needs to be interpreted and compiled each time it runs. Between jigsaw modules and this, we should see some nice improvements in startup time.

I don't think this is right, is it? I think this change is more about consistent performance than startup performance.

For me the JVM starts really quickly; the only performance issues I've seen there are related to large bloated frameworks doing too much at load time. I don't recall the std library being a factor at all (and why do you think it is recompiled every invocation?)

The JEP explains it pretty clearly. "Improve the start-up time of both small and large Java applications, with at most a limited impact on peak performance."

Right. "Java Applications". Not the JVM.

This is very exciting! Question for the experts out there, do you think this has the potential to do away with using the JNI in new projects for the speed boost?

This change has nothing to do with JNI whatsoever.

The JVM has always (well, not always, but for 15+ years) run Java code by first compiling it to native code. The only difference is that the JVM will now allow you to optionally do the compilation ahead of time, in order to decrease an application's startup overhead. This actually hurts performance of the compiled methods, since runtime profiling is not available to the AOT compiler (but the document also describes a "tiered" mode, where AOT-compiled code can be dynamically replaced with a better JIT-compiled version at runtime).

If you want to link your Java code with native code written in a non-Java language, that's a totally different requirement, and JNI will continue to be the way to accomplish it.

> and JNI will continue to be the way to accomplish it.

Although if you don't like JNI, you can use JNA [1] (which I believe uses JNI to link to libffi, and libffi for the rest).

[1] https://github.com/java-native-access/jna

> JNI will continue to be the way to accomplish it.

Not on Java 10 hopefully.

There already are alternatives for JNI. You can use JNR[0] and JNA[1] which allow you to access native libraries by writing java.

In some future version panama[2] will offer similar functionality to JNR.

[0] https://github.com/jnr/jnr-ffi [1] https://github.com/java-native-access/jna [2]http://openjdk.java.net/projects/panama/

C# had this for a while with ngen.

C++ had this for even longer. Assembler doesn't even need a compiler..

C# and Java are very similar. That is the only reason I mentioned it.

Right, Assembler only needs an assembler

Still needs a linker

Pffft... you're using a libc, or something? Direct Syscalls[1] are where it's at.

[1] https://en.wikibooks.org/wiki/X86_Assembly/Interfacing_with_...

Isn't java already compiled ahead-of-time?

You give the JVM a .class file, not a .java file.

Though this is a technicality.

Java 9 will be able to compile java source code to java byte code then compile that java byte code to native machine code, correct?

It is compiled to intermediate byte code but not machine code. You still need the JVM to JIT the byte code to something the CPU can deal with.

Not necessarily. Java byte code can be run directly on a JPM (Java Physical Machine).

Are there any that support the current class file format? ARM jazelle is no longer being worked on. So I would be surprised if there is anything that can do Java SE directly. JavaCard of course being quite different than standard Java.

Java bytecode is too highlevel for it to be suitable to run directly on hardware. Each instruction can map to multiple machine instructions. A JIT or AOT compiler can optimize the code on a lower level. A hardware implementation cannot do inlining, loop unrolling, hoist array length checks out of a loop, etc...

compile means "native code" here, not jvm bytecode.

Look at class file sometime. It is basically bad C code in appearance. It is nowhere close to assembly type code, which is what the final output of the JIT is.

Maybe I'm crazy, but the bytecode dumped from a class file definitely looks more like assembly than "bad C" to me, personally: https://gist.github.com/anonymous/e824444ea158beb7b72b26fbf1...

Important restriction:

for the initial release, the only supported module is java.base

I.e, we will not be able to compile our own code ahead of time just yet.

> I.e, we will not be able to compile our own code ahead of time just yet.

That's not really true. From the same doc:

> AOT compilation of any other JDK module, or of user code, is experimental.

So it's "experimental", but possible to do.

What, if any, effect might this have on Android, given that its all Java?

None — Android doesn't use Hotspot; they've had their own AOT compilation project for their platform (ART) for some time.

This probably does not affect android. In 5.0, android switched to AOT with a new VM, ART instead of Dalvik, which was a huge win for performance. Jitter in many, many apps went away completely, especially when scrolling. This did cause install times to increase, however. In 7.0 (or 7.1?) there is a mix of JIT with AOT for code that is deemed hot by a profiler, hopefully bringing the benefits of AOT without the lengthy install times.

Android and Oracle's Java have been diverged for quite a while. There aren't any Java 8 features available to Android now, so you sadly shouldn't hold your breath for any Java 9 features either, it will probably be a long, long time.

>>There aren't any Java 8 features available to Android now

that is incorrect. https://developer.android.com/guide/platform/j8-jack.html

Just plopped this into my activity to make sure: someList.stream().map(String::toUpperCase).forEach(System.out::println);

As long as minSdkVersion is 24 or higher you should be good.

Except it doesn't work and is full of bugs.


Probably none. Android runs on a different implementation of the JVM called Android Runtime (ART), previously Dalvik.

Android is not JVM so it won't have much affect on it.

Applications are open for YC Summer 2018

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact