
The JVM is not that heavy - khy
https://www.opensourcery.co.za/2017/01/05/the-jvm-is-not-that-heavy/
======
gregschlom
Also worth noting that the JVM itself only weighs a couple of megabytes. The
bulk of the size comes from the Java runtime (ie: the "standard libraries"),
and there are lots of things that your app may not need there (XML parsing,
serialization, etc...)

A couple of years ago I wrote a simple tool
([https://github.com/aerofs/openjdk-trim](https://github.com/aerofs/openjdk-
trim)) that allows you to filter out what you don't need. We were able to get
the size of OpenJDK from 100MB down to around 10MB.

Note that the work of determining which classes you need is entirely manual.
In our case I used strace to check what classes where being loaded.

~~~
derefr
> I wrote a simple tool that allows you to filter out what you don't need

It'd be a short hop from here to a tool that basically does for JDK-platform
apps what Erlang's releases do for the ERTS platform: builds a new JRE (as a
portable executable, not an installer) that actually _contains_ the app and
its deps in the JRE's stdlib, such that you just end up with a dir containing
"a JRE", plus a runtime "boot config" file that tells the JRE what class it
should run when you run the JRE executable.

With such a setup, your Java program could actually ship as an executable
binary, rather than a jar and an instruction to install Java. Nobody would
have to know Java's involved! :)

~~~
yoden
[https://docs.oracle.com/javase/8/docs/technotes/guides/deplo...](https://docs.oracle.com/javase/8/docs/technotes/guides/deploy/packager.html)

Not only is it a short hop, it already exists :P

~~~
radicalbyte
The problem with visiting that site is that Oracle have started litigating
against users of their JVMs.

In that way the JVM can be "heavy".

~~~
pjmlp
With users that use commercial features without paying for them.

It is quite easy to know which features those are when they require a flag
named _-XX:+UnlockCommercialFeatures_ , you just don't use them by mistake.

~~~
geodel
Oracle gives free license to use commercial features in development[1] in
section B. It is very easy to some script for JVM startup parameters and get
that script deployed in production by mistake.

1\.
[http://www.oracle.com/technetwork/java/javase/terms/license/...](http://www.oracle.com/technetwork/java/javase/terms/license/index.html)

~~~
pjmlp
Quite right, but unless I am too cynical I doubt those deployments were
actually done by mistake, when I relate how many companies try to "alleviate"
their costs.

------
martingxx
I led our teams to switch from Java to Go because of the productivity of
development, but then noticed deployment was simpler and faster, memory usage
was slashed (for comparable applications), request/response times were much
more consistent, startup was practically instant and as a result we started
aggressively rewriting Java applications to Go and saw a notable difference in
the number of machines we needed to run in AWS.

So in my situation, the JVM is heavier by every single measure listed, and for
each by a considerable margin.

~~~
brianwawok
> aggressively rewriting Java applications to Go and saw a notable difference
> in the number of machines we needed to run in AWS.

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.

~~~
martingxx
These apps are mostly microservices and the Java ones are mostly only a year
or two old. None of them use things like spring. Some use Dropwizard. Would
you consider dropwizard modern? If not, what would you use instead?

~~~
nostrademons
Take a look at the TechEmpower benchmarks:

[https://www.techempower.com/benchmarks/](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?

~~~
sk5t
On first glance the dropwizard test app appears to be doomed to mediocrity via
reliance on hibernate.

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.

~~~
imtringued
What's wrong with hibernate? The only thing I can think of is that you're not
using "JOIN FETCH entity.relation" when accessing collections and end up with
the N+1 select problem but that is because you're using any ORM incorrectly.

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.

~~~
sk5t
Well, for benchmarking the essential framework, which does not mandate any
ORM, I would want to use something for data access that takes the question of
time spent on type reflection, internal caching, and the like, out of the
picture. Hibernate and EMF have their place, but not as part of benchmarking
the thing that hosts 'em. Core Dropwizard performance is all about how it uses
Jetty, Jackson, and maps requests to resources and operations.

------
nikcub
Microsoft seem to have learned a lot from Java in designing their new .NET
Core CLR. It has gotten almost everything right:

* a small and fast CLR (JVM)

* a class library that defaults to almost nothing but primitive classes

* proper and standardized version, platform and package management (NuGet)

* open source and MIT license[0]

* a patent promise[1]

* arguably the best dev IDE available (Visual Studio) and one of the best up-and-coming dev text editors (VS Code)

* Native ORM, templating, MVC, web server so there is one way to do things

* open source middleware standard (OWIN)

* they left out, for now, attempting the hard ugly stuff like x-platform GUI

* all platforms are equal citizens, they acquired Xamarin for dev tools and release their own Docker containers.

* it's already getting good distribution (on RedHat) even tho it's only 6 months out from a 1.0 release.

Java may have missed the window for fixing some of these issues in their
platform - I feel that if Android were being developed today, they'd almost
certainly take .NET Core as the runtime.

I've yet to commit to using .NET Core anywhere, but from what I know about it
so far it is impressive.

[0] [https://github.com/dotnet/coreclr](https://github.com/dotnet/coreclr)

[1]
[https://raw.githubusercontent.com/dotnet/coreclr/master/PATE...](https://raw.githubusercontent.com/dotnet/coreclr/master/PATENTS.TXT)

~~~
frant-hartm
I could more or less agree with most of it apart from

> arguably the best dev IDE available (Visual Studio) and one of the best up-
> and-coming dev text editors (VS Code)

[https://www.jetbrains.com/resharper/documentation/comparison...](https://www.jetbrains.com/resharper/documentation/comparisonMatrix_R2016_1_vs2015.html)

Refactoring, Coding assistance, Navigation & search sections being most
important.

~~~
alimbada
Although the last version I used seriously was VS2013, VS on its own is pretty
mediocre. With ReSharper though, nothing beats it in my opinion.

On the other hand I've been using Eclipse and IntelliJ for the past year.
Eclipse is not even worth talking about but even IntelliJ does not come close
to vanilla VS in terms of usability. Again, my opinion.

~~~
EGreg
What is better than VS? PHPStorm etc?

~~~
alimbada
I actually can't name anything better. I was just saying that whilst VS is
"the best", the best isn't really that great (without a plugin from
Jetbrains)...

------
jhh
I agree with many points in this article. That being said, there are
dimensions of heaviness not captured in the article as far as I can see:

1\. The startup times, not so much of the JVM itself, that just takes 1,5
secs, but the startup time of your application gets higher if you have a lot
of classes on the classpath. I guess it's the classpath scanning that takes a
lot of time (?).

2\. Memory usage of Java objects is quite heavy. See this article:
[http://www.ibm.com/developerworks/library/j-codetoheap/index...](http://www.ibm.com/developerworks/library/j-codetoheap/index.html)

3\. The heavyness of the ecosystem in terms of the magnitude of concepts and
tools being used and the enterprisy-ness of libraries.

~~~
akvadrako
In my mind, 1½ seconds is huge; that essentially rules out any interactive
usage. It's even annoying for rapid development cycles. Only low expectations
or heavy orchestration can overcome such a startling disadvantage.

~~~
jeremiep
That's completely false in the context of a Lisp.

I boot the JVM once and iterate endlessly in the same process. Same for
ClojureScript in the browser or node.js. Lisp is by far the most interactive
language there is with the fastest iteration times (AFAIK).

1.5 seconds would be huge if you had to constantly restart your application
like you do everywhere outside Lisp. Iterating in Clojure is literally
instant.

I wrote applications in dozens of languages, and none come remotely close to
Clojure's iteration speed or joy of use.

~~~
bandrami
_Lisp is by far the most interactive language there is with the fastest
iteration times (AFAIK)._

That's Forth. Lisp comes next.

------
linkmotif
This interview with Bob Lee is really interesting on this topic:
[https://www.infoq.com/interviews/lee-java-
di](https://www.infoq.com/interviews/lee-java-di).

Apparently, Square was first built out on Ruby with the mindset that the JVM
is an old clunker.

Fast-forward a few years they switched to the JVM because it was faster and
the language (I know, not related) provided compile-time safety.

~~~
twic
> Apparently, Square was first built out on Ruby with the mindset that the JVM
> is an old clunker

Ah yes, this would be the same industry where people lead their teams to
switch from Java to Go because they believe it will improve the productivity
of development.

~~~
jakevn
If one doesn't switch technologies to improve the efficacy of their team, why
ever switch technologies? Should we simply use the first technologies
conceived until the end of time?

------
Jeaye
Java, especially JAR files, can be quite light weight. However, JVM
environments, and development with Java and Clojure, can be very heavy _and_
slow.

For Clojure, starting `lein repl`, takes 16 seconds on my 2012 Macbook and 9
seconds on my similarly-aged Dell laptop, both with SSDs and i7 quads.

Regarding memory usage examples, the base memory usage of a Google App Engine
instance running the move trivial Hello World Java program takes around 140MB.
Given that the default F1 instance has a soft memory limit of 128MB, it
becomes clear that the JVM is working against you in both cost effectiveness
(the price to spin up new instances as your existing ones are already above
the soft limit) and latency (since spinning up instances is slow). Add Clojure
on top and the problem certainly doesn't get any better. As an added
annoyance, which is specific to App Engine but a result of using the JVM, it's
impossible to specify JAVA_OPTS, so any of the -X flags, without switching to
the Flexible environment.

As a result of both of the above, choosing Clojure for developing on App
Engine, as my specific example, has had the serious downfall of slow
development tools and memory issues out of the gate on my instances, causing
me to pay more for a beefier instance class. The REPL is really hard to beat,
but the combination of JVM and Clojure are the biggest pain in the ass, with
this stack.

~~~
jwr
Yes, the startup is slow. But nothing afterwards is. The JVM gets bad press
because of startup time while in reality that hardly matters.

~~~
Jeaye
In production, what matters is the ridiculous memory usage. Both Java and App
Engine are to blame about this, but the Python and Go folks aren't running
into the same issue.

~~~
CountHackulus
If memory usage matters to you, have you tried telling the JVM not to use all
the memory? Have you tried any of the tuning options? Can't say I've ever used
app engine, but the pure java applications I've worked on did in fact use a
fair bit of memory, much like windows and OSX will aggressively use spare
memory for caching. Then I use -Xmx to tell it not to use all the memory and
now it's much better. For a server, I'd say that this is both expected and the
correct behaviour.

~~~
beagle3
I have, and gave up after a month of touching every couple of days trying to
find the sweet spot. Someone more familiar with JVM internals would have
probably succeeded - but somehow C Python Go and even OCaml runtimes don't
need this level of tuning in my experience.

JVM deployments tend to assume nothing else happens on the same machine, in my
experience.

~~~
eklavya
You last point is probably true. In every application I have ever deployed I
only ever set the Xmx and J-Server settings, I never faced any problems. You
need to give the GC some breathing room though.

------
saosebastiao
Interesting that all the comparisons were with server frameworks. As if
anybody ever cared about a few hundred megabytes of overhead on a server.
Hell, even a bloated JVM implementation fits in most server L3 caches.

On the desktop, laptop, phone, or embedded environment, the JVM _is_ heavy. It
starts up slow, jars carry around ridiculous amounts of dead dependencies,
garbage collectors require immense amounts of tuning, etc. And we shouldn't
really expect otherwise. If you can't even keep your VM in cache, how are you
supposed to have fast application code?

Specialty closed source JVM vendors have done wonders in terms of improving
this problem...but it's still an uphill battle. AOT native compilation down to
machine code is becoming more popular _because of_ the proliferation of
resource-constrained environments, and it will take time for new
languages/compilers to take over, but take over they will.

~~~
froh42
Haha, AOT native compilation.

This comes back time and time again. AOT native results in slower runtimes for
applications with one simple exception: startup time. In every other case a
modern JIT compiler like the JVM will win due to gathering information and
layered compilation.

Where AOT really makes sense is for an interactive app on a mobile device
where you don't care about the last millisecond of performance but startup
times and even much more importantly: energy expenditure. (That's why google
AOTing the apps on device startup is quite sensible)

Most funnily Microsoft was heavily advertising AOT with .net framework 1.0 but
in general switched to dynamic profiling and optimization in later versions of
.net. (System assemblies that _everybody_ uses during startup are AOT compiled
using ngen, however)

It is just not "one size fits all", depending on your platform and
requirements you'd have completely different requirements to your virtual
machine. What you want is different between interactive use and "batch
processing" and between energy starved devices and big iron.

Java - while ironically advertisted for "applets" years ago - is optimized for
the latter case and there it really shines. On a server with long running
processes AOT makes no sense at all.

So what AOT will take over is phones. IOT devices. Everything were energy is
at a premium and startup times need to be quick. Layered JIT compilation takes
over where you want to squeeze out the last bit of total performance. (Even
interactively, looking at you, Google V8 and Chakra)

~~~
quanticle

        AOT native results in slower runtimes for applications with one simple 
        exception: startup time. In every other case a modern JIT compiler like the 
        JVM will win due to gathering information and layered compilation.
    

That's not necessarily true. JIT compilation is severely constrained in the
amount of analysis that it can do for the simple reason that JIT has to be
_fast_. Fast enough to not noticeably slow down the app. Meanwhile, an AOT
compiler can take all the sweet time it needs, and roam all over the program
in order to discover optimizations.

JIT compilers work very well on untyped languages like Smalltalk because the
compiler can discover the type information at runtime, and then pre-compile
the types that it sees most often. But that's not really that useful on the
JVM, because Java is typed, as are most other JVM languages, with the
exception of Clojure.

    
    
        Most funnily Microsoft was heavily advertising AOT with .net framework 1.0 
        but in general switched to dynamic profiling and optimization in later 
        versions of .net. (System assemblies that everybody uses during startup are 
        AOT compiled using ngen, however) 
    

Actually, with .Net Native, Microsoft is back to advertising AOT.

[http://blog.metaobject.com/2015/10/jitterdammerung.html](http://blog.metaobject.com/2015/10/jitterdammerung.html)

~~~
froh42
Not all JIT compilation needs to be fast. I think it was hotspot that first
does interpretation, then - when interpretation proves too expensive -
switches over to a quick jit. And when code gets executed lots of times it
runs jit again, this time with deep optimization settings.

What I personally don't understand: Why don't we cache JIT results between
runs? That might be a worthwile optimization and even possible in the face of
class loading.

It probably would be like running ngen on .net, just WITH performance
statistics of a program. (Enabling specialization of calls for types commonly
passed or eliminating constant expressions while keeping the generic version
of a function around - that's hard in AOT as you need profiling information. I
think sun's C/C++ compiler was able to do that for AOT, resulting in large
speedups. But maybe it only used it for branch prediction).

Edit: What I forgot to add - I like the way you could always AOT things in
.NET with ngen but also use a JIT where possible. Now that Java turned out to
be owned by the evil empire and .NET the one by the company committed to open
source - imagine reading that 10 years ago - I'm really curious in which way
things will develop. And with all the new contenders as well. JVM (and .net)
is not dead, but _a lot_ of interesting alternatives are getting traction now.

~~~
pjmlp
> I think it was hotspot that first does interpretation, then - when
> interpretation proves too expensive - switches over to a quick jit. And when
> code gets executed lots of times it runs jit again, this time with deep
> optimization settings.

This is configurable, Hotspot can JIT right away when application starts, but
then be prepared to wait a bit.

> What I personally don't understand: Why don't we cache JIT results between
> runs?

They do, just not the OpenJDK that many only care about.

All commercial JDKs support code caches between executions and AOT
compilation.

------
cperciva
The notion that the JVM is not heavy because it needs less than a GB of disk
space seems crazy to me. I consider OpenSSL to be wildly bloated because it is
over 1 _MB_.

~~~
gozur88
A megabyte of disk space is now worth about $0.0000290, according to this
site:

[http://www.jcmit.com/diskprice.htm](http://www.jcmit.com/diskprice.htm)

The numbers we're talking about here just aren't a practical consideration any
more.

~~~
cperciva
The disk space is cheap, sure.

But the CPU time spent by the dynamic linker resolving thousands upon
thousands of symbols? That's actually rather painful.

~~~
gozur88
You must be very busy if two hundred milliseconds is painful.

------
sunkencity
Sure it takes a while to load and there's bloat, but the bloat is everywhere
now.

On the bad site of the JVM and assorted Java tools is that they are second
class citizens of the unix world. The command arguments are all messed up,
much like a windows tool ported to unix, and the interaction with the rest of
the unix stack like sockets, files are all solipsistic and off, which leaves
an ill stink on everything touched by it.

One of the things I find funny with java is the once upon a time much touted
security model, fast forward a couple of years and the event of android -
using the unix security model and none of the java stuff.

~~~
stcredzero
_Sure it takes a while to load and there 's bloat, but the bloat is everywhere
now._

This is exactly the kind of development culture that produces heavyweight,
unresponsive tools.

------
nightcracker
OP is impressed by running 5 processes at once while claiming that the JVM is
not that heavy.

Is this cognitive dissonance? Dishonesty? I don't understand.

~~~
geodel
I think it is genuine sense of wonder of a web developer. I have been told
many times to update my ancient hardware when I say Java is memory hog and
slow on a 6GB Windows7 laptop.

Some people don't think that those massive 16/32G MBPs etc with SSDs are not
available to everyone.

~~~
vardump
6 GB? Your laptop is probably not running optimally, because 2 GB of address
space has just 64-bit bus, 4 GB has 128-bit bus.

You should ensure both memory modules are same size (say, 4 GB or 8 GB),
otherwise performance can suffer noticeably.

~~~
geodel
It was given by company I was contracting for few years back. I recall Laptops
were 'upgraded' to 6GB from 4GB to give developer better performance.

I think my main point was making luxury as basic because even more luxurious
stuff exist.

------
hardwaresofton
I was a little surprised that he author disliked "heavy" things, yet kept
reaching for the absolute heaviest tools in their respective categories:

\- Rails (just about the heaviest web framework ever made for ruby, despite
it's wide appeal)

\- Ember (I absolutely love ember, but it is by far the heaviest modern JS
framework... I don't include things like ExtJS)

Also, I routinely use the heavy/light distinction, but it seems in a
completely different way. I almost don't care how heavy something that run on
the server-side of a web application is, on the back-end "heavy" generally
translates to "contains complexity I'm not willing to deal with". "heavy" on
the frontend for me means both in footprint and complexity.

------
vvanders
Start-up times are still an issue with Clojure on the JVM. For instance with
Android I've found the initialization times to be pretty much a show-stopper
for any application development.

~~~
lnanek2
I don't know anything about Clojure, but in modern Android development,
Instant Run patch files mean installation isn't even done each change any
more. Even then, you can avoid a lot of installation time by using an emulator
on a fast development machine instead of a real device. For most of Android's
life the emulator has been disgustingly slow, but for installation times, it
has benefits. Meanwhile restoring from a snapshot instead of booting fresh
each time, x86 emulator images, and Intel's virtualization engine mean the
speed isn't so bad any more.

~~~
vvanders
It has nothing to do with that and more to do with that last time I tried it
the start-up times for an app was multiple seconds on top of base start times.

Given how often Android evicts apps that's something I'm not comfortable with
shipping. Would love to use Clojure but it was definitely a show-stopper for
us.

~~~
dman
What did you use instead?

~~~
vvanders
Stock Android/Kotlin.

------
relics443
I've been using these arguments at my company for years. There's definitely
FUD surrounding the JVM, and it's pretty ridiculous. Sure, it's not a perfect
system, but it's usually disregarded for being "old and bloated".

------
Perseids
> I run at least 5 JVM processes on my 2012 MacBook Pro with 8GB of memory.
> This is all day, every day. I would never have tried to start 5 Rails apps
> at the same time.

Where have we gone wrong that starting 5 processes with 8GB RAM seems
impressive? On my development PC I regularly run: - two different browsers
(Firefox and Chrome), - an Email Client that is a slimmed down browser suite
(Thunderbird), - two chat apps and an IDE that are browsers in disguise
(Electron and Chrome App). And that is without me running and testing any of
the applications that I'm actually developing. Oh, and then automatic testing
starts yet another browser. Even better, my actual application runtime
environment then runs in its own full OS virtualization, because otherwise the
deployment environment differs from my development environment… If we can't
slim down the runtime environments of our day to day apps and development
tools, how are we going to survive the end of moore's law with the ongoing
trend to hide everything behind more and more abstraction and virtualization?

And I disagree with many others here, that RAM usage just doesn't matter for
server development. At my last project, our setup contained a few macro
services and the ELK stack for logging which accumulated to five JVMs and
three Node instances. Now this is ok for the live setup, because most of these
will run on different machines anyway. But for testing you want to have them
all on the same machine, for convenience on the Jenkins machine. And you want
separate setups for integration tests, user acceptance tests, and demo
purposes. All of these have basically no load, but still consume the full
amount of RAM. Of course, you will say, just get more machines, we are in the
age of the cloud! But that doesn't come for free: Now every Jenkins job needs
different credentials to access the machines, all developers need access to
every machine, every new setup needs an additional cloud provisioning step,
possibly with approval from management because of the additional fees. And
yeah, you can automate most that away, but building and maintaining that
automation also carries its own burden. All of that for something that should
be essentially free – it's not like my OS doesn't already run a few hundred
processes when I have just started my window manager.

------
rb808
Not just heavy but I really don't like all our processes named "java" with
stupid -D cmd line parameters. A Nice native binary app will let you can name
it what you want with config as you like it.

~~~
jackmott
there are ahead of time compilers for java! not free though.

~~~
AnimalMuppet
IIRC, gcj compiles to an executable.

~~~
lisivka
Gcj was deleted from GCC in October 2016[1]. So only free option left, AFAIK,
is to use mono AOT[2].

[1]: [http://tromey.com/blog/?p=911](http://tromey.com/blog/?p=911) [2]:
[http://www.mono-project.com/docs/about-mono/languages/java/](http://www.mono-
project.com/docs/about-mono/languages/java/)

~~~
AnimalMuppet
Or a copy of GCC from September 2016. (That's not going to get you Java 9
support, I realize...)

~~~
josefx
It is not going to get you full Java 5 support either. The project was dead
before the OpenJDK even existed and it never got better.

------
CaptSpify
I feel like I'm missing something. His argument seems to be "the JVM isn't
heavy compared to other large and bloated systems". Well... sure. My car isn't
heavy when compared to a tank, but if I want light, I'll use my bike.

------
jmspring
I've never had a problem with Java the language being heavy. However, many
code bases due to annotations, dependency injection, etc. from a development
perspective really aren't any longer Java. You need to understand the code
base, the app itself, etc.

This happens with open source projects as well. I contributed to the Azure
support for JClouds and the bulk of my ramp up time was understanding how
things were done more than writing the code itself.

~~~
abvdasker
I could not agree with you more. My most recent job doing Java dev at a major
US tech company has really soured me on this style of Java. Annotations beyond
null/nonnull seem to obscure the code and make it far less maintainable.
Besides being largely superfluous the DI frameworks — primarily Dagger — I've
seen widely used at said company have led to numerous production memory leaks
because they obscured object scope and lifecylce from engineers.

------
djsumdog
A lot of Java apps are shit at packaging too. They often include an entire
Tomcat server with all the setup files you don't even need. I wrote this a
while ago:

[http://penguindreams.org/tutorial/embed-tomcat-in-your-
appli...](http://penguindreams.org/tutorial/embed-tomcat-in-your-application/)

..but don't do that. Instead use something newer like netty and ditch that
decades old crappy servlet layer you don't need.

You can also use sbt+onejar or sbt-native-package to make either a single jar
runnable or a standard deb/rpm/tar.gz package to run your service.

------
ysleepy
Java does not give memory back to the system very quickly per default. This
blows up the memory allocated to the jvm considerably.

start it with:

    
    
       java -XX:+UseG1GC -XX:MinHeapFreeRatio=5 -XX:MaxHeapFreeRatio=15 -jar ...
    

and the jvm will give back to the system. see
[http://imgur.com/a/m9Qxx](http://imgur.com/a/m9Qxx)

~~~
josefx
> -XX:MinHeapFreeRatio=5 -XX:MaxHeapFreeRatio=15

TIL. Why are those XX flags?

------
bsaul
i think most people wouldn't say the jvm is heavy compared to ruby or python
runtimes, but rather golang , rust or swift. Aka : 1 file copy deployment,
almost no boot time and 0 memory bloat.

the first time i ran a server in go and realized it took a few kilobytes in
ram when nothing happened, i was quite in shock.

~~~
snuxoll
1 file is the stupidest argument I've ever heard for saying one language is
better than another.

Look, here's the 1 file it takes to install a python app I wrote:
mycoolapp-0.1.0-1.el7.rpm - how neat is that?!

Sure, pretty much anything is "heavy" compared to go or rust, but those are
systems programming languages by design, not something I'd write some huge web
application in personally.

~~~
lmm
> Look, here's the 1 file it takes to install a python app I wrote:
> mycoolapp-0.1.0-1.el7.rpm - how neat is that?!

Is that one cross-platform file? Is it even portable across different linux
distributions? Across different servers running the same distribution but
perhaps with different libraries installed? Will another python developer
understand how the build process for it is set up and be able to add new
dependencies?

~~~
snuxoll
> Is that one cross-platform file?

No, and neither is a Go or Rust binary, next question.

> Is it even portable across different linux distributions?

Nothing preventing me from taking an extra 10 minutes to modify the spec to
support SUSE, Fedora support usually comes for free if you support el7.

You like Debian derivatives? Let me toss a debian/ directory in there, that'll
only take a couple minutes too.

Added benefit, I'm not just throwing files at a server like some hacky Windows
developer doing an xcopy deploy to IIS. I can check what version of my
application is deployed, and update it along with the rest of the system if I
so desire (setting up a yum or apt repository isn't hard).

> Across different servers running the same distribution but perhaps with
> different libraries installed?

Different libraries? Do you mean different VERSIONS of libraries? Native
libraries have figured this shit out for ages with soname's. Python too,
different versions of an egg can be installed side by side, you need to pin a
specific version just use pkg_resources.require() in your main script.

> Will another python developer understand how the build process for it is set
> up and be able to add new dependencies?

I had a Jr. Developer with no experience with Linux or Python pick up building
the package and making basic edits to the .spec file 10 minutes. RPM/DEB
packaging isn't magic, you describe your package with metadata, write some
shell commands to build/install your package in a buildroot, and then list the
files from said buildroot to include in the package. You could make your first
package from scratch in under an hour if you read the Fedora or Debian wiki
guides on packaging.

~~~
lmm
> No, and neither is a Go or Rust binary

Sure, I'm comparing with the JVM per the article.

> Nothing preventing me from taking an extra 10 minutes

Indeed, but 10 minutes here, 10 minutes there, it all adds up.

> Different libraries? Do you mean different VERSIONS of libraries?

No, I mean some native libraries not installed. Does your package declare what
packages it depends on? How do you handle different distributions using
different package names for the same libraries.

> RPM/DEB packaging isn't magic, you describe your package with metadata,
> write some shell commands to build/install your package in a buildroot, and
> then list the files from said buildroot to include in the package. You could
> make your first package from scratch in under an hour if you read the Fedora
> or Debian wiki guides on packaging.

Sure, none of it's hard. But if there's no clear standard everyone ends up
doing it slightly differently, and then every project you pick up you have to
understand how they've set things up.

~~~
snuxoll
> Sure, I'm comparing with the JVM per the article.

Fair enough, though I still use RPM's to deploy Java (Spring Boot even!)
applications.

> Indeed, but 10 minutes here, 10 minutes there, it all adds up.

In the grand scheme of software development updating the .spec file or debian
control file is peanuts.

> No, I mean some native libraries not installed. Does your package declare
> what packages it depends on? How do you handle different distributions using
> different package names for the same libraries.

In the case of RPM based distributions, some conditional macro's in the .spec
file that swap out Requires/BuildRequires statements based on the distribution
the package is being built for. I never bother with SUSE personally, but there
are differences between EL7 and Fedora that I have to keep track of.

> But if there's no clear standard everyone ends up doing it slightly
> differently, and then every project you pick up you have to understand how
> they've set things up.

.spec files are more standard than most build tooling. The only thing that
complicates them is projects without an adequate build system in the first
place, everything else is minor style differences based on who wrote the spec.

Everything has been done before, unless you are using some extremely new or
extremely niche language or build tool chances are your spec file will be easy
to figure out, since any and all complexity is explicitly linked to how easy
it is to build and install your software in the first place.

------
vmarovic
"For both Node and Ruby you need a C compiler on the system which is hundreds
of megabytes alone." Wait what? What c compiler is hundreds of megabytes?

~~~
makapuf

      $ ls -sh /usr/bin/gcc-5
      896K /usr/bin/gcc-5
    
      $ ldd /usr/bin/gcc-5 
    	linux-vdso.so.1 =>  (0x00007ffc64bf5000)
    	libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fda3da4f000)
    	/lib64/ld-linux-x86-64.so.2 (0x000055f2460a1000)
    

(so no specific .so dependencies)

And why would you need that in production ? (hint: use fpm)

This article seems strange : why do you include xcode in npm ? why use a mac
if it's that heavy ? sure an IDE is nice but I wouldn't take that as part of
the language. Or also include eclipse + plugins.

~~~
noselasd
I certainly agree that you don't need that for production machines.

However /usr/bin/gcc is just a frontend, and calls a slew of other
binaries(such as cpp, collect2, cc1, normally found somewhere in
/usr/libexec/gcc/). You also need binutils, and to be useful, likely headers
for at least the standard C library.

The gcc + binutils package comes up at around 75MB on my machine.

~~~
makapuf
I stand corrected - duh of course I should have added called binaries. So it
seems 100M is the right ballpark.

------
it
I keep seeing plenty of evidence that the JVM is indeed heavy. When I was
working at a startup and we were running Solr on the JVM, it kept running out
of memory and crashing. When I tried using Clojure I was irritated by the
startup time of the REPL on the JVM. More evidence:
[http://stackoverflow.com/questions/13692206/high-java-
memory...](http://stackoverflow.com/questions/13692206/high-java-memory-usage-
even-for-small-programs).

If you want something light like Clojure and don't need any Java libs, try
Pixie. [https://github.com/pixie-lang/pixie](https://github.com/pixie-
lang/pixie)

If you want something light not like Clojure, Go is a great choice. It's fast
to compile, fast to run and doesn't gobble up your memory unless you force it
to.

~~~
diek
If you ran a game written in C++ that kept running out of memory and crashing,
would you say C++ is "heavy"? Solr (and Lucene internally) maintain large in-
memory data structures as well as memory map (usually) on-disk segment files.
How much memory they use is determined by many, many configuration options
within Solr. This has nothing to do with the JVM.

Same thing with Clojure. It basically bootstraps the entire Clojure
environment on each process start. The JVM itself starts up in tens of
milliseconds.

------
djsumdog
What the hell is an HCMB? Nothing on DuckDuckGo, and nothing on Urban
dictionary. I wish people would stop using acronyms before defining them.

~~~
raidancampbell
Closest I could think of was a typo on Intercontinental Ballistic Missile, but
your comment is on the first page of google results.

------
geodel
So JVM is not heavy compared to even heavier stuff. However compared to Go it
is quite heavy in term of disk, RAM usage, and deployment.

~~~
omginternets
Exactly. I see where the author is going with his article (and I think some of
the points he raises are actually quite valid), but he's playing both sides of
the "heavier than what?" point.

Yes, the JVM is slimmer than many interpreted languages with external
dependencies (Python, Ruby, etc), and yes it can be slimmed down through
manual labor, but _no_ it is not something you can call "not heavy" with a
straight face.

------
outworlder
Interestingly, the author does not touch startup times.

Frankly, for server-side loads, no-one cares how much your runtime weights, be
it disk space, download size and even memory (heck, my last project required
developer workstations with at least 96GB).

There are all sorts of environments where that matters. And that's one of the
reasons why Clojure didn't catch on on Android.

~~~
rev
Wow, 96GB of RAM? I don't even... Would you care to elaborate?

~~~
Macha
We have applications that require 100GB of RAM to run.

The result being that they're not run locally. At least we have alright tests.

------
tlrobinson
Well, I sure wish I knew how to make our Clojure dev server (`lein ring
server`) take less than 2 minutes to start up on a 4 core i7 16GB MacBook Pro.

Fortunately I typically only need to restart it when switching branches.

~~~
iLemming
There's maybe just too much stuff required in user namespace? We were able to
address many problems including this one when we switched to boot-clj

------
hannob
I must admit my experience is a few years old, but one thing that the whole
text doesn't mention and that has contributed a lot to the negativity I feel
towards the java ecosystem: It seemed not well integrated in the Linux
ecosystem.

What do I mean? I often experienced that Java dependencies were not readily
available in Linux distros. Packaging Java stuff was - weird and complicated,
not sure how to better phrase it.

For Python/Ruby/PHP you usually can rely on the fact that major libraries are
properly packaged. For Java not so much.

~~~
twic
Because Java distributes applications as bundles including the libraries (fat
JARs, WAR files and so on), libraries need to be available to the builder, not
the installer. That means it's perfectly sound that they're in Maven Central
(and competitors), and not in the OS's package manager. It's the same with
packages in JavaScript, Ruby, Go, Erlang, etc.

The only things you might need to install through OS packages are the JVM, and
perhaps an application server if you're doing things that way, which fewer and
fewer people are.

When i first started working with Java on unix, i felt the same way as you - i
wanted the libraries to come through the OS package manager, the same way
native libraries do, and spent ages trying to get my deployed applications to
use them. Eventually i realised i was just doing it completely wrong.

------
sandGorgon
I used to think this too, until I came across
[http://www.scylladb.com/](http://www.scylladb.com/)

It is a fork of cassandra written in the Seastar c++ framework and is drop-in
compatible with cassandra. Claims 10x increase in performance.

I always thought there was a few percentage points difference - never a 10x
performance difference between java and c++. And that too for a project with
as many man hours and facebook-scale tuning as cassandra.

~~~
uluyol
I don't believe their claims. Many benchmarks (including those done by
ScyllaDB) are done badly. They'll take a database built to operate on larger
than memory data (e.g. 10x) and run on a dataset that can fit entirely in
memory. So whoever optimized for in memory wins. But run on an appropriately
sized dataset or reduce system memory and you see little difference.

This might seem like a good thing (ScyllaDB gives you extra performance when
you have the memory for it), but it does mean that if your dataset grows,
performance falls off a cliff. Something to keep in mind.

~~~
fnord123
"it does mean that if your dataset grows, performance falls off a cliff."

Are you saying you know ScyllaDB does not handle larger datasets and Cassandra
is better in this respect? Or are you saying that their benchmarks are not yet
conclusive?

~~~
uluyol
I am saying that when you go from fully in memory (due to having a small
dataset) to having to move things to and from disk, disk increasingly becomes
your bottleneck rather than memory. And disk is much slower than memory.

~~~
fnord123
I thought a main point of Cassandra was to be distributed so the working
dataset could stay in memory across the cluster. And the smaller memory
footprint you typically get when you're not in the JVM means more of your
working dataset can be cached in memory. So I would expect superlinear
speedups compared to Java for exactly the reason you describe (depending on
the request distribution).

But yeah, I'm always up for pouring over more benchmarks. :)

Here are more details on benchmarks here:

[https://qconsf.com/system/files/presentation-
slides/avikivit...](https://qconsf.com/system/files/presentation-
slides/avikivity_slides.pdf)

The YCSB benchmark suite they use is the same one as used in this paper from
the Cassandra homepage:

[http://vldb.org/pvldb/vol5/p1724_tilmannrabl_vldb2012.pdf](http://vldb.org/pvldb/vol5/p1724_tilmannrabl_vldb2012.pdf)

------
DrBazza
We run an algo trading system using 10-20 JVMs depending on exchange. It's not
so bad.

------
mi100hael
If you're installing a compiler on your production server, you're doing it
wrong.

~~~
falcolas
And yet we do that every time we install the JVM (and Ruby, and Python,
and...)

~~~
deepsun
No, when you install JVM (you probably meant JRE) on the server -- there's no
`javac` (compiler) installed, only `java` -- JVM. I never needed `javac` on
production server.

~~~
falcolas
The JIT is a realtime compiler, so yes, there's still a compiler when you put
the JVM on a machine (whatever form you use).

Of course, I know of a lot of developers who just put the whole JDK in a
Docker image to save on the complexity of having to manage two different
installs or containers.

> I never needed `javac` on production server.

Good; that's how it should be; but not how it always is.

~~~
mi100hael
JIT is part of a platform's runtime environment, not part of its build
environment. Since you appear to be a super-pedant, I'll revise my initial
statement to:

 _> If you're installing any tooling or programs on a production server or
opening ports other than those strictly necessary for running your production
application (as a pre-built binary or package whenever applicable) conforming
to industry standards for that application/server environment, you're doing it
wrong._

------
w8rbt
Jars are just awesome for cross-platform work or for when you need easy
deployment. I oscillate between Java and Go now for similar tasks. They are
both great for cross-platform and easy deploys/frequent updates. Go is better
at systems stuff (that's expected as it _is_ the new C IMO). Java is better if
you want a boat-load of rich data structures at your finger tips (more than
slices, structs and maps... Go feels bear bones here, but I like it that way
just as I like C that way). They both perform about as well as C and C++ for
most things and are safe and fun to use. I like C and C++ too, but I'm getting
too old to use them.

------
liveoneggs
The reputation of "heavy" was hard-earned back in the bad-old-days (1.3 era)
when EVERYTHING NEEDED to be written in java and the JVM still _sucked_.

I, literally, had a party at work when we got our web app to three days of
continuous uptime without an OOM error; nevermind that the early JIT (1.4 era)
took 12+ hours to get "warmed up" and give peak performance.

Don't misunderstand me- java's horribleness has given me a pretty nice career
so, for that, I love it. For the years and years of broken promises- (OSGi
without running out of PermGen? lol) I hate it.

Java is not lightweight by any means; computers are just faster and have more
memory.

~~~
deepsun
I think topic poster point was that _other_ ecosystems (JS and Ruby) became so
heavyweight that JVM now looks light in comparison.

~~~
liveoneggs
It's true. node.js issues also pay the bills.

------
alsadi
Ruby is perl-minded folks reinventing python without understanding it. The
result was: ruby is python-done wrong.

Now comparing python flask uwsgi and jvm jetty apps are in favor of python in
all metric.

Starting a django elephant takes no time compare that to starting less capable
framework of choice in java world.

To be fair, java can be much much faster than python. But usually you don't
care because python is not the bottleneck. Ex. The bottleneck can be in the
SQL query

~~~
stcredzero
_Ruby is perl-minded folks reinventing python without understanding it. The
result was: ruby is python-done wrong._

This is something said by someone who has no clue about the Smalltalk
influence on both Python and Ruby. (Though Guido was very critical of certain
things Smalltalk did, and made a point to do certain things very differently.)
Ruby is very much Perl redone by someone who very much wanted a Smalltalk-like
object system, but with much more syntactic sugar.

~~~
alsadi
Talking about ruby community, thread safty was too late it's only usable in
ruby 2.x and rails v. 4.

And even with rails v4 many apps are not thread safe like canvas lms because
the long tail of rails addons that are not thread safe and the common bad
practice of using static properties to store non-sharable states and
properties

------
Jach
Work on an enterprise-sized "app", the JVM starts seeming "heavy". It feels
super slow (and memory greedy, and you have to make sure it has enough of the
right 'type' of memory) in executing on a whole (when it gets going it can do
limited, specific things quite fast) and for productivity, as does all the
tooling around it. Unless perhaps you're Google and you have server farms
constantly compiling crap and so on so devs don't have to notice as much. Most
of the negative feelings are probably the fault of having a ginormous app in
the first place, I'd likely feel similarly about C++. Still, even when it's
just a somewhat-large app (like a database, or an IDE) I've felt it in Java
whereas working on a similarly large app in other languages doesn't have the
same feeling. I've never really felt it when just writing a REST/SOAP API
that's effectively a thin wrapper around some DB calls. Like a blog could be,
but there are many other similarly small things. But those sorts of small
problems can be done effectively in most any language, and 'heaviness' is
probably very low on one's priority list...

I think there's an incentive with more dynamic languages to decompose your
software into smaller bits. When the language gives you the ability to
"script" that helps even more. You don't need to bundle everything into an
uberjar, you can run things independently, and therefore you don't even need
all of the sources locally, just what you need to do your particular bit of
data processing. It's possible to do this with Java and multiple JVMs, but
it's hard, the incentives aren't there. Unfortunately I don't have experience
with Clojure in the large to say whether it helps make the JVM feel lighter,
from my side projects it seems like it could but I don't know if the community
is going that way. Lispy languages have different incentives since they let
you build from the bottom up so well.

~~~
mike_hearn
I think a part of the reputation of Java being big and slow comes from its
popularity in the enterprise. This is partly because in that space you're
usually writing apps for a captive audience (your fellow employees) so there
isn't much incentive to optimise. The business managers understand things like
"the app has feature X by date Y" but don't really understand or care about
"it is productive to develop on this app" or "the app uses half as much memory
as last month". Those things make the lives of developers nicer, but don't
change much about the business.

Moreover, I think enterprise software managers often don't really have a grip
on how much work needs to be done or how long it should take. So you can get
situations where a team of say 10 people is staffed up to build an in house
app, they deliver it, there are some improvements that can be made, they
deliver the improvements, etc. After a few years the app is largely in
maintenance mode and doesn't need much done to it, but ... who wants to fire
the loyal employees who understand the app? Unless there is another app of
roughly the same size and type waiting in the wings, what can happen is the
team starts doing busywork. The managers don't notice because they aren't
programmers to begin with and can't tell the difference between "creating a
new in house framework because no reasonable alternative exists" and "creating
a new in house framework because we're bored".

So over time enterprise software can bloat to extreme levels. Combined with
Java's verbosity, and the fact that a long time ago it really was very slow,
you get a platform with a reputation for ponderousness that is only partly
deserved.

------
david-given
Way back when I ran a comment engine that was a custom Java servlet running on
an embedded (i.e. mostly interpreted) JVM on a NSLU2: a 266MHz ARM with 32MB
RAM. The servlet container was Winstone. Can't remember what the JVM was,
sorry.

Load wasn't exactly high, but it worked absolutely fine.

~~~
david-given
Ah, it was JamVM.

[http://jamvm.sourceforge.net/](http://jamvm.sourceforge.net/)

Alas, the last release looks like it was 2014, although it does claim to
support Java 8. The actual interpreter core is under 100kB (class libraries
extra, of course).

It plugs into the OpenJDK! Look for the openjdk-8-jre-jamvm package in Debian.

------
jwr
What most people seem to miss is that if you use Clojure, the startup time
hardly matters, because you do not restart your development JVM often.

I find this similar to discussions about boot time. It doesn't matter -- I
reboot my computer once a month, if even that.

------
my123
Note that you can also use IKVM and then Mono AOT if you don't want a JIT at
all.

------
eikenberry
I see no mention of the additional cognitive load a complex runtime adds. This
to me is the 'heaviest' part of the JVM. Though I admit it is not necessarily
the same class of things the author is discussing.

------
PaulHoule
Clojure is heavy, or at least it has high start times. Some of that is the JVM
start, but parsing and compiling a large amount of Clojure code system-wide is
more of a burden than, say, CPython.

------
ericfrederich
You know it's not heavy because there are blog posts about it being not heavy.
I also know Python's GIL isn't a problem because there are numerous posts
about it not being a problem

------
justinsaccount
It's not the JVM, it's the tooling.

~~~
flavor8
Which tooling specifically? Going from Java to Python a couple years ago I was
in shock about how immature the tooling in the Python world is by comparison.

~~~
realusername
I also hate the Java tooling as well personally, it's my #1 complaint with the
language and one of the reason I avoid it. I would say that nothing really
follows unix principles and seem over-engineered, everything is quite complex
to grasp to become proficient.

~~~
eklavya
I don't know when I used Haskell after using Scala, the first thing I missed
was the JVM tooling. There is nothing I have seen ever that comes near.

------
nhumrich
If you don't think the JVM is heavy try running it on a t2.micro. It can never
get enough memory to start. I haven't ran in to any other language runtime
that won't run on a t2.micro

~~~
paulddraper
Huh? I ran Atlassian Stash (now Bitbucket Server) on a micro while trialing
it.

That's a many-hundreds-of-MB Spring enterprise behemoth of a Java server.

Have _you_ ever tried running Java on a micro?

------
ohstopitu
Just out of curiosity: If you decide to use Java (or any other languages that
run on JVM), are their 3rd party libraries as "nice" (read: as many) as npm?

~~~
hkjgkjy
Former node dev, currently Clojure here.

Npm has more abundance of good packages. They are typically better documented
and easier to get started with, sadly :(.

JVM has some really great stuff - things which are lightyears ahead of what is
there in NPM. Much of which started as university projects, as Java is popular
at schools.

I wish JVM developers took a hint from others and started making very easy and
fun documentation, but have no high hopes.

~~~
mike_hearn
Can you give some examples?

I've usually found docs to be pretty good in the Java library space. One of
the nice surprises about it.

~~~
hkjgkjy
Hi Mike! Big fan of your work! Have been for years, so it's a pleasure seeing
you have replied to my comment.

My latest example of this is the Apache Commons-Net Java package [0]. I wanted
to make a toy Telnet server as an example for a friend asking how to do so.

I gave trying to install the library a good 20 minutes in my evening at home.
Couldn't find a simple Maven "this is how you install" and no "easy 1-2-3 get
started with this library" text either.

After looking around for a while, I decided to check how to do it in Node.
It's super easy, you just do

    
    
        require('net').createServer((socket) => socket.write('Hello from a toy telnet server!')).listen(8080)
    

And that is all! Got my task done in 5 minutes, and my friend learned
something easy. My takeaway is that for software to be successful, being
technically sound is only the first half of the marathon. You also need to
make it accessible.

[0] [https://commons.apache.org/proper/commons-
net/](https://commons.apache.org/proper/commons-net/)

~~~
mike_hearn
A telnet server is just a socket connected to a pty, no? I'm not sure there's
much to it, which is why it's so easy in node.

I guess in java you'd do the same program something like this:

    
    
        ServerSocket server = new ServerSocket(8080);
        while (true) {
            try (Socket sock = server.accept()) {
                sock.getOutputStream().write("Hello world!".getBytes());
            }
        }
    

It's a bit more verbose, but hey, that's Java.

I think maybe the issue there is you got distracted by the idea that you
needed a library. Commons-Net doesn't actually provide a telnet server because
it doesn't need to.

That said, I agree that Commons-Net doesn't have great docs. I think it's
fallen out of use over time. These days if you wanted a powerful non-blocking
socket library you'd use Netty or VertX. The docs for Netty are much better:

[http://netty.io/wiki/index.html](http://netty.io/wiki/index.html)

~~~
hkjgkjy
Cheers for the example. The Commons-Net library was where I ended up after
some searching - so my experience is of someone who wants to get from 0 to 100
asap.

Cheers and have a good day!

------
stevefeinstein
That cough medicine doesn't taste that bad. If you have to use "that". It's
the thing.

------
rahilb
I wish I was as good as the developers commenting how slow java is to start.
They are clearly on a higher plane of enlightenment where 1.5 seconds to start
ruins their day, their deployment process, and development cycle.

More power to them.

------
doggydogs94
The biggest problem with Java is not the JVM, but versioning. Many Java
applications encounter difficulties when the wrong version of Java exists on a
computer. This leads to many siloed computers to maintain.

------
sjg007
And it is better than a segfault.

------
vacri
> _I, for one, am relieved not to have run apt-get install build-essentials on
> a production box._

Well, whoever does this is Doing It Wrong.

------
debacle
JV-what? I just installed nuget on ubuntu and what is this?

