Jvm.go: A JVM written in Go
github.com
github.com
We need more people doing crazy sh*t like this. Java is a fantastic runtime - and a great language. But it has a huge amount of baggage. I'd love to see experiments int the open source arena playing around with alternatives to the standard Oracle JVM.
I'd love to see Android like alternatives for the desktop that re-use java's syntax but have less baggage and are not tied to Sun's view of what Java should be (Oracle's view of the language is actually a lot better than Sun's thank god).
There are countless Java developers who would like to reuse their knowledge but in a different set up. E.g. desktop not server, lightweight not heavyweight, systems level (like go/python) etc.
I keep hoping that one of these JVMs will end up going in their own direction one day not trying to achieve official Java compatibility.
Anyway kudos to the author.
As a side note, I really wonder how an engineer can use ghetto talk like "crazy sh*t" and especially in this forum here.
Excuse me?
Second, wealthier people swear more[3]. So not only are you racist, you're also wrong.
Third, there's a great deal of research showing the usefulness of profanity. It conveys emotional content in a way that other words can't. If you refuse to accept and understand profanity, you're neutering the language.
1. http://www.merriam-webster.com/dictionary/ghetto
2. (On that note, "ghetto" is often used by racist Americans as a pejorative euphemism for "black".)
3. http://newsfeed.time.com/2013/04/10/nine-things-you-probably...
What you said was racist, whether you intended it to be or not. Look up the definition and use the word "ghetto" correctly in the future. Using a very loaded word incorrectly is far weaker than saying "crazy shit".
Speaking of crazy shit: if it's neither swearing nor profanity, why won't you spell it correctly in your quotes?
Anyway, your argument here isn't intellectual unless you have some functionally equivalent suggestion to replace "crazy shit" with. And, like I said, profanity has additional emotional content, so you can't replace it with anything that isn't profane without losing some meaning.
[0] https://en.wikipedia.org/wiki/Demographics_of_California
Take it easy - until you know the language well enough to know when someone is using a complement like 'crazy sh*t' - I wouldn't rush to judge them. Context is everything - as the first two words of this comment attest. Context is everything :-)
http://en.wikipedia.org/wiki/List_of_Java_virtual_machines
And I have no idea what you mean by baggage. I am assuming you mean "features" like JNI, JMX etc ?
If that is the case then the modularisation of the JVM is something that has been underway for a number of years now. It is targeted for Java 9 release:
http://openjdk.java.net/projects/jigsaw/
And there is no difference in the way Oracle or Sun has managed the JVM. Changes are still made through the JSR/JEP process.
And finally again no idea what you mean by countess Java developers wanting to reuse their knowledge but in a different environment.
Android is already an option as is Swing but honestly does anyone care about desktop apps these days ?
Yes there are many JVM:s but most of them aren't any good.
I guess if you mean by "not any good" they're slower/less featureful than the original HotSpot JVM, then, well, yes..... you get what you pay for (in terms of resource usage).
Nothing in particular has changed, but full generics C++ style imply value types, and value types are now on the table whereas before they were not (other higher priorities, I guess).
> And there is no difference in the way Oracle or Sun has managed the JVM
Yet coincidentally more positive changes have happened to the language in the last 3 years than the previous 10? I see a language that was dying on it's feet coming back to life - so hence my feelings about Oracle's stewardship (right or wrong!).
> And finally again no idea what you mean by countess Java developers wanting to reuse their knowledge but in a different environment.
Almost every Java programmer I know and/or meet has their 'other language'. That they use to solve problems that Java has failed in. But a common frustration is the need to relearn a similar but subtly different syntax. Concrete examples are NodeJS (and hence Nashorn, Vert.x et al) for lightweight format neutral APIs. Android for mobile :-) so hat's a win. Go for systems (Python in the past). Objective-C et al Desktop.
For me there is no concrete reason why we can't have these in Java (language). But in doing so we need to be willing to throw away components that don't fit. I.e. existing APIs, existing philosophies. Java is much more than the language, however so when tackling problems that aren't large scale serverside applications we need to adapt if we are to reuse. This is an area that I very much am interested in seeing develop. My specific case in hand is Android - which reuses Java skills but has a lot less to do with normal Java programming.
Hope that clarifies a bit.
I may be naive. Am I missing something or this guy is an incredible code machine?
* Predefined explicit requirements (a tight spec).
* No distractions.
* No colleagues (i.e. you're working on a non-blocking single thread of execution).
* Enthusiasm.
* An unhealthy enjoyment of coding.
I have worked at this pace and I'm sure many others have, but you need to have those pre-requisites (and they are RARE!).
Bare in mind that if you're the only developer those commits probably haven't been tested and you're not worrying about damaging other people's code.
Of course, you can't scale that model :-)
Which btw is a fantastic real world analogy of why multi-threading can suck horrifically in some cases and why that parallel execution isn't always a good thing.
NOTE: None of that takes a way from a totally awesome and fearless project to take on and complete (which I believe it is?).
I checked my stats and over the last six weeks I have dedicated my spare time (of which there has been more than usual, but I have a family and work 9-5) to my current project, and I've averaged 7 commits per day with 59308 lines added, 22903 deleted.
I am feeling a little burnt out now, but fortunately the code is essentially done and all that's left is a little mop up and writing a blog post.
- How is the performance?
- Is a GC implemented separately or is the Go one directly used (awesome!)?
- How do calls to native JNI things operate (through CGO)? Does it work?
What is a lot of work is writing a high-performance JVM (with a good optimizing JIT and a good GC), getting the details right (especially the Java memory model), and supporting "advanced" features such as JNI and JVMTI.
Graal is one part of a JVM, the JIT compiler, written in Java [0]. It performs about as well as C2, and sometimes better [1].
[0] http://openjdk.java.net/projects/graal/
[1] http://lampwww.epfl.ch/~hmiller/scala2013/resources/pdfs/pap...
Saying Graal performs about as well as C2 and sometimes better is modest. The Graal/Truffle combo does a lot more than C2 can ever do. It is only really comparable if you ignore the astonishing capabilities it has vs the competition.
For readers who are not aware of this work, and who have an interest in VM/compiler technology, I strong recommend checking out Chris' blog and the Graal/Truffle presentations that are floating around. Basically they've built a program that converts simple syntax tree interpreters into full blown JIT compilers. It means that basically any toy scripting language can have similar performance to, say, Javascript on V8, just by writing the base interpreter with their framework.
But where it gets really crazy is when you write an interpreter for C or (say) Objective-C, and start to get aggressive speculative just in time compilation with seamless cross language optimisation, to the extent that C code can actually be run on a compacting garbage collector.
That actually sounds a lot like what RPython from PyPy enables.
The performance of various RPython interpreters like PyPy and HippyVM are pretty impressive.
http://cesquivias.github.io/blog/2014/10/13/writing-a-langua...
I've yet to read through [1], but the series above (so far up top 4 parts) gives a nice overview of truffle/graal -- and some ideas as to how it is different/similar to rpython/pypy. Be sure to also skim the comments, as they provide some input to why things are/starts out slow, and how to fix it (if it can be fixed).
Didn't realize there'd actually materialized any actual released code from the graal project -- glad it has (quite a while ago, apparently)!
Besides the sibling post, JikesRVM is one of the most well known ones.
I'm guessing not great. Looks like a simple bytecode interpreter using interface virtual dispatch on the instructions (!).
> - Is a GC implemented separately or is the Go one directly used (awesome!)?
As far as I can tell, it just uses the native Go GC, which is smart.
Edit: so I really am a cynic, I count at least two on the first page and neither are at all as wanky as my imagination likes to think.
Coming soon: scala.go (!)
Last time I checked there was a half finished student project that does this. But not a full implementation. That's a shame. I've encountered a Go shop that was really suffering from things as basic as "our best debugger is gdb which doesn't really work" and "how do we get a stack trace from our running program?".
The Go crowd like to talk about how Go programs are small and standalone, but obviously the HotSpot JVM is not just a big pile of NOPs. You can get very small implementations of Java too, but only by cutting lots of useful functionality.
I bet if a company produced a solid, compliant Go for the JVM, that'd be a license to print money. I feel like lots of startups are coding themselves into a corner by relying on the relatively new and simple Go runtime. If they could bring their code across to the JVM and get access to all the useful tools it has, that'd be worth some money.
Debuggers are definitely a weak spot, though, I agree. Luckily it's being worked on (https://github.com/derekparker/delve).
Bear in mind "compile to native code" is a bit vague. JVMs compile bytecodes to native code too, they just do it on the fly instead of ahead of time. If you mean "single executable" then there are ways to do that with Java too, check out the downloadable demos on the Avian website. But many native apps are not single files and have lots of libraries they depend on, so the distinction there isn't obvious either.
The fact that Go programs are all statically-linked (easy deployment, no weird dependency issues) and are reasonably safe given idiomatic coding patterns are nice bonuses.
We can appreciate them for the ideas they present, the interesting implementation of features, and the what-if's that can come from expanding the hack further.
Pure Java Hello World launches in 90ms on my machine. Jython Hello World takes 1.3 seconds.
EDIT: to address all the comments.
I am saying the JVM isn't _too_ slow for command line applications. Not ideal, but tolerable.
I just tested the startup time of a robovm'ed Hello World: 23ms FWIW. And the resulting executable isn't exactly light weight.
$ otool -L Main
Main:
/usr/lib/libSystem.B.dylib
/usr/lib/libiconv.2.dylib
/usr/lib/libsqlite3.dylib
/System/Library/Frameworks/Foundation.framework/Versions/C/Foundation
/usr/lib/libstdc++.6.dylib
$ du -sch Main
11M MainIf not, then don't say "All JVM implementations are slow".
So, on my machine, Hello World takes about 80ms to launch (and terminate), but writing grep in Java isn't the best idea as it will take a while for the program to achieve "native" speed.
HotSpot shines when running long-running processes, where the JIT is able to perform optimizations few (if any) static compilers can. Java 9, however, is expected to include JIT caching/AOT compilation to help programs that need to start at full speed.
Of course, there are JVMs out there that do AOT compilation rather than JIT, and they don't have a "slow startup".
> startup time of Clojure has nothing to do with the JVM
Startup time has everything to do with the VM. Check out this post, comparing perf and startup time for Clojure on the CLR vs JVM:
http://stackoverflow.com/questions/10827093/clojure-performa...
23ms is is pretty good. To compare, Hello World in Python, converted to a native executable has a launch time of 6ms (284k executable size). So there might be some room for improvement. RoboVM is still amazing.
Actually there is no single "the JVM," even today. Various JVMs exist, commercial and free, that have their individual strengths.
A subset do, for sure. But some of us are just playing around.
Sometimes it is done just to learn, but it seems a bit silly to do it in public as it were.
I mean how likely is it that "Hashtable/JS interpreter/JVM implemented in C" is going to be a big hit on HN? Not often. But since Go, JavaScript, and other insert new hotness language here are popular things somehow it's more interesting to retread old ideas with them. That's not the sign of a young master demonstrating his skill, it is the sign of an immature field that hasn't figured out how to distinguish what is new and important from what isn't.
It's unfortunate in particular for the people who do do these projects for fun or learning. These people have their work hijacked for a showoff culture's mutual backpatting.
For apps, it matters less but you still have to think about how easy it is to modify. That's why we care about open source, right?
A good pitch? Why does that even matter? 97% of these projects are for fun/as a learning exercise. If someone is interested those things, then they can check it out. If they aren't, then I guess the author misses out on a few GitHub stars. shrug
I wish the README had more information about the reason this project exists. Is it just a fun toy jvm for learning? Is it meant to be eventually production-ready and performant?
Just knowing whether something is meant as a learning project or for production use vastly changes how people will approach it and I just can't tell with this one.
It would be an interesting concept to pass through Java objects for the GO garbage collector to deal with but that sounds incredibly difficult or impossible.
I think it's actually much simpler to do it this way. It keeps the mapping between Java and Go constructs much tighter.
Still a cool project either way.
As long as the Go garbage collection works, it shouldn't affect how the program runs. That's kind of the whole point of GC. Hell, you could write a toy VM with no garbage collection, and it would work fine until you blew your memory.
Sure it can, and that appears to be what this JVM does. There's nothing in the JVM spec that says you have to implement your own GC any more than you have to implement IEEE floating point numbers yourself. In fact, I don't think the JVM mentions GC at all. It just assumes infinite memory.
If your implementation platform (in this case Go and the Go runtime) gives you something, by all means use it.
It seems like it must mention something about finalizers.
> A relevant post by the author (English translation): http://translate.google.com/translate?hl=en&sl=zh-CN&u=http:... .
Relevant (autotranslated) snip from the blog:
>> Go itself is garbage collected language, so there is no separate jvm.go achieve garbage collection mechanism.
I saw the following code and noticed the commented out "gc" function and assumed it meant it was just "not yet implemented but will be" vs "unneeded". I wish the code was actually documented somewhat.
https://github.com/zxh0/jvm.go/blob/dd74e6227e9d78ad8ec191ec...
I've also been in a position where I've exclaimed something "clever," only to find out later that it actually revealed a point of ignorance.