So in my situation, the JVM is heavier by every single measure listed, and for each by a considerable margin.
So in my situation, the JVM is heavier by every single measure listed, and for each by a considerable margin.
This is the easy trap to fall into though. What if you aggressively rewrote the Java apps from crappy legacy frameworks to well developed Java apps?
A rewrite ALMOST always is faster. So the new language seems faster. Except if you would then rewrite the rewrite back in the original language... you could even still be faster.
Very hard to split apart what is faster because the rewrite got rid of lots of bloat, and what is faster because it is legit faster. Java is legit fast when it is written well. Also very easy to make a bloat fest.
https://www.techempower.com/benchmarks/
DropWizard is modern, but it isn't fast. Go and even Node.js are significantly faster. If you want performance, you cut layers out of the stack - check out the numbers for raw servlets or even just straight Jersey annotations in that benchmark. If I were doing JSON-over-HTTP microservices in Java, I'd likely use straight Jersey + Jackson, or if performance was really a problem, Boon over straight servlets.
What framework did your Go rewrite use? The standard libs?
Call me crazy, but I like my dropwizard with Spring DI for (singleton) resource setup, a micro-ORM to get work done, and HikariCP datasources at runtime.
Entity framework has include and active record has includes which do the same thing. The qt ORM also has something similar.
The only ORM I have seen that lacks this critical feature is odb. It doesn't allow setting the fetching strategy on a per query basis. You have to either always use eager loading or lazy loading which basically makes it useless for my purposes.
Any benchmarks to provide in order to support this wild claim?
The main advantages that Go has over Java is that the standard library is brilliant - thus obviating the need for folks to create monstrous frameworks (and losing performance) and that Go has better memory utilization because of value types (structs) and because it is AOT compiled. Unfortunately Java JIT as designed by the JVM devs takes a lot of memory.
In raw performance, I would still give the edge to Java over Golang though.
Also, when you do the rewrite you have already solved the domain problem that you did not fully understand when implementing it the first time.
But deployment, gc pauses and startup time (jvm vs go) are orthogonal to program quality. I would also expect go to have less memory usage.
> deployment was simpler and faster, memory usage was slashed..., request/response times were much more consistent, startup was practically instant
At the end of the day despite Go's failings it's a good (maybe the best?) language for large projects and teams because it compiles fast, is easy to anyone to run anywhere, tests run quickly, programs execute quickly and there is already good tooling/editor support.
Nothing beats efficient workflow for improving velocity.
For my usages its a reasonable language.
PHP is a great velocity language, provided you have a small(er) team or are willing to commit to additional controls on how you write your PHP (document types/structure of arguments mainly) to ensure that your PHP code is able to be read quickly by other developers.
Personally I prefer Go here because it enforces good readability by default and therefore scales better with team size.
And in PHP7.x you have even more type hinting than before and with an IDE like PHPStorm refactoring is a breeze.
And with the release of PHP7, PHP is future proof. The community will continue improve it with the major features, they have shown it. Interest in the language have increased. More RFCs is contributed to the language than before. https://wiki.php.net/rfc
Multiple teams on a large code base is not really a problem in modern PHP. I do it every day. We follow modern design patterns, code reviews, code coverage over 80% of the system (old as new code). New code is probably over 95% coverage. Deploys regularly multiple times every week.
Almost all (>95%) of my problems stem from design decisions made in the past, not the language itself.
I'm not saying that you should not use Go (or Java). Both are fine languages. Use the right tool for the job. If you don't do a realtime stock trading system or some embedded system, but some web stack, I can't really see that the majority of the problems stem from language choice (whatever you choose). It is in the team, the culture, the understanding of the domain. There should be your focus.
Personally, the most two important things I look for in a language/platform is tooling and community.
Indeed.
It's a typical honeymoon phase with very little regards to 1-2-5 years in the future. The cost of having picked to Go will be fully apparent then.
I really feel like that one of the big issues we as programmers want to get a better handle on but there isn't a lot to go off that isn't based off opinions (which can be hard to validate).
The power of Java is that there is more than one JVM and that can really save you a lot of money/developer time if the world changes under your ass ;) i.e. had a JVM based graph database, ran it on Hotspot -> big GC pauses, moved to Zing no more pauses. All we needed to do is run a different VM and problem went away (new problem was of course that Zing costs but not much, also now with Shendoah coming for free we could probably have moved to that)
With GO you can't do that yet. If your app is not latency, bound but throughput bound there is no place to switch too other that a rewrite. That flexibility of deployment on JVM tech gives us a lot insurance for no costs, until we need it.
We hired some Node maintainer(s) a long time ago, rumor has it, who got us on the Node train.
Unfortunately it seems difficult to use (to me at least), but frameworks like netty are build on top of it to provide incredible performance.
However, the fact that Java provides real threading means that a blocking io is not a performance problem if you use the correct patterns.
The tooling, especially for runtime operations, are so much superior to the golang options its night and day. I have much more success modeling complex business models in java with its better type system, and for doing low latency work its much easier to do on the jvm due to the availability of better libraries (which may get better in go) and the concurrency options are miles better on the jvm.
Go's stack allocation and gc defaults make for easy management in most of my default cases. The ease of adding http endpoints to things is phenomenal. Being able to write easy cli applications in the same language I write daemons in is great.
All told, I think for simple daemons and cli's I'd go golang, for more complex systems I'd go jvm.
I, personally, think the binary deployment thing is overblown. I've never had any problems deploying jvm applications and the automation to do either seems essentially the same to me.
As for the relative "heaviness" I think golang definitely feels lighter, but that is largely because golang apps do less. Once you start having them do more they start to "feel" just as heavy as java apps (for whatever "feel" means).
* [edit] called golang heavier meant lighter
I also run these in on cloud platforms that auto scale. The golang processes spin up very quickly, the java ones not so much.
In these two respects the JVM is heavy compared to golang for my very common scenarios. The heaviness also causes me to spend more money for the JVM solution.
I have an app that people were complaining took too much memory. A quick look with VisualVM showed that its actual heap usage when idling was only 50 mb but because we hadn't set any heap size limit, it was reserving hundreds of megs from the OS. The idea is that it can run faster if it does that. The fix was simply to use the -Xmx option to tell it to use less memory and GC more often.
In other words, JVM deployments need a lot more tuning than Go and they will generally need a lot more memory as well. But you're right, not setting -Xmx at all will make the JVM look worse than it really is.
$ ps -eo rss,cmd,user | grep jenkins
4928228 /usr/bin/java -Djava.awt.he jenkins
$ ps -eo rss,cmd,user | grep drone
12940 /drone agent root
19924 /drone server root
We run the two applications in the same machine. Admittedly Jenkins is much feature-rich but we only use its vanilla settings without whatever fancy plugins for a few legacy SVN repos.P.S. The Drone server and agent are running within docker containers.
[1] https://www.joelonsoftware.com/2000/04/06/things-you-should-...
Of course "Go was Faster". It's because you started with a clean slate!
I think the perception of Java suffers a lot because it will consume all the RAM on your machine by default if you let it (but not immediately). It's a very poor default because even though there are technical arguments for doing that (goes faster), they aren't well known and people tend to assume "more memory usage == worse design".
There are a lot of myths about the JVM out there. We can see on this thread the idea that it takes 1.5 seconds to start being repeated multiple times, each time someone else points out that it's actually more like tens of milliseconds to start.
I wonder if Oracle documents are plain wrong for JDK 8 docs for maximum heap size[1]:
"Smaller of 1/4th of the physical memory or 1GB. Before Java SE 5.0, the default maximum heap size was 64MB. You can override this default using the -Xmx command-line option.
Also Oracle has chosen correct defaults because it took Java long time to shed its reputation of being dog slow and if they optimize for memory it will start looking worse in performance.
1. https://docs.oracle.com/javase/8/docs/technotes/guides/vm/gc...
I can get it to start around 30-50mb, but as soon as you hit it with traffic the memory usage jumps up.
I second that. I have deployed a medium traffic web-server written in Scala backed by a postgresql DB on 128MB VPS, back in 2009!
> I think the perception of Java suffers a lot because it will consume all the RAM on your machine by default if you let it (but not immediately).
I don't think that is true. The default heap size for Oracle and OpenJDK VMs has been bounded as far as I remember. In fact, I would like it if the VM, by default, allowed the heap size to grow upto available RAM when GC pressure increases, but that doesn't seem to be the case as of now.
Edit: Did you mean non-heap VM arenas grow indefinitely? If so, I am not aware of them.
Edit: do you have a twitter or Reddit account? I'll ping you when I have code examples if you want.
Have you reported to Go devs? Sounds interested use case.
A lot of this has to do with another unmentioned, terrifically annoying property of the JVM: pre-launch min/max heap allocation. Standard operating procedure is to go with the default, and overbump it if your needs exceed it. I can't possibly imagine how many petabytes of memory are unnecessarily assigned to JVMs throughout the world as I type, apps consuming 79MB with a 256MB/512MB heap size.
(I'm sure a chunk of the difference is due to a better understanding of the program during rewrites.)
Please refrain from making statements like this unless you have a reproducible quantifiable analysis.
If you really wanted to demonstrate the effect you describe you'd need to have the same team rewrite the application twice, once Java->Java, once Java->go, making sure to align the program structure as much as possible (making exceptions to take advantage of lang specific features of course).
If you were to do that, then that would be interesting! No one does that of course because it's expensive and wasteful from a business perspective, but it's the only way to determine anything useful.