A couple of years ago I wrote a simple tool (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.
Already today you can build a custom JDK in the early access release.
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! :)
We fixed this whole class of issues by doing exactly what you suggest: bundling the JRE and writing our own launcher binary.
Not only is it a short hop, it already exists :P
In the future, we'll hopefully have the Substrate VM [1] for Java and other Truffle-supported languages. It's embeddable and also does reachability analysis to exclude unused library code. For now, it seems to be closed source.
[0] http://readytalk.github.io/avian/
[1] http://lafo.ssw.uni-linz.ac.at/papers/2015_CGO_Graal.pdf
That's the difference between an industrial-strength platform like Erlang, and a dev-centric deployment nightmare like Python. Java is normally on the enterprise side of the spectrum, but unfortunately it didn't get deployment right for quite a long time, even though it appears it's getting there lately.
Also, Proguard's config is pretty complicated and the results are hard to understand. Our approach (openjdk-trim) is dumb simple: unpack the java runtime jars, use rsync to filter out entire directories we don't need, pack it back.
It's a simple, brute-force approach compared to Proguard's advanced static analysis, but in this case it gives better results. Maybe a good example of "worse is better".
I think once there is official way to trim JDK down, making deployment super easy and fast ( Single executable File ), Java will pick up stream again.
The only problem and hesitation we have...is Oracle.
Why is it so big? What do we gain?
I don't have a system with 10MB of cache, so I imagine Java can't run faster than memory...
Several points:
* Who said the 10MB is all used at once?
* I don't know your hardware, but there is very, very good chance you are actually quite wrong about <10MB of cache. These days, most magnetic disks have more cache than that, and if you are using SSD's, there's a boatload more cache than that in there.
* If you were referring strictly to CPU cache, then I'm even more confused, because the entire existence of that stuff is predicated on it being faster than memory, so... (and even still, if your total CPU cache isn't 10MB, it likely isn't that much smaller).
* It's not like the whole package would sit in RAM the whole time anyway. By your same assertion, I could say that one of my CPU registers is only 64-bits wide, so I imagine all programs larger than 64-bits can't run faster than L3 cache...
I'm not sure why you'd say it is too big. The article page is 1.4 MB alone... and it still needs to leverage a general purpose runtime/JIT that is orders of magnitude larger to do its single fixed purpose.
For comparison, a C++ wxWidgets 3.0 application isn't going to be much smaller than 10MB in release mode if you statically link it. Much as I hate to admit it, 10MB just isn't that big in an age of terabyte SSDs and systems with 32GB of RAM.
Can't tell if sarcastic or... o_O.
In the unlikely case you're actually serious, you really need to rethink your perception of memory costs in 2017.
BTW, libruby-2.3 is 2,5M, just the shared object file, and it tries to use all aforementioned stuff from the underlying UNIX.
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...
3. The heavyness of the ecosystem in terms of the magnitude of concepts and tools being used and the enterprisy-ness of libraries.
Where do you get these numbers from? On my five year old MacBook Pro with default JVM options parsing a 20 MB file:
real 0m0.248s
user 0m0.325s
sys 0m0.043s
> 2. Memory usage of Java objects is quite heavy.
That's IBMs enterprise VM that uses three word headers. HotSpot is actually better. If you compare that with other "lightweight" programming languages it is really, really light.
A quarter of a second to start up the VM, run some code, and exit again is actually pretty steep compared to typical interpreted and compiled languages. Among other things, this means that you can't really call Java executables from a loop in a shell script.
For comparison purposes, both Ruby and Rust will show between "0.00 elapsed" and "0.02 elapsed" for a simple "Hello, world" program on my laptop.
1. Startup time being addressed by precompiling the standard library (or your own library). See "JEP 295: Ahead-of-Time Compilation": http://openjdk.java.net/jeps/295. Also addressed by modularisation of the standard library, "JEP 220: Modular Run-Time Images".
2. Memory usage (and less garbage collection overhead) using value types. See "JEP 169: Value Objects": http://openjdk.java.net/jeps/169.
You don't have to use the enterprisey libraries though. Using Dropwizard, for example, gives you a tight and performant set of libraries that have a fairly minimal learning curve and require relatively little boilerplate.
$ time java -jar target/uberjar/clojure.jar
Hello, World!
1.29s user 0.08s system 181% cpu 0.755 total
$ /usr/sbin/system_profiler -detailLevel full
Model Name: MacBook Pro
Model Identifier: MacBookPro11,3
Processor Name: Intel Core i7
Processor Speed: 2.3 GHz
Number of Processors: 1
Total Number of Cores: 4
L2 Cache (per Core): 256 KB
L3 Cache: 6 MB
Memory: 16 GBThese are the kind of lazy generalization that causes people to make poor technology decisions.
To add,
4. Garbage collection and lack of value typed records. As far as I know there is currently no way around going full SOA (structures of arrays (of primitive types)) for large data collections.
Object overhead (memory usage) and GC overhead are the reason why only SOA will work (and it's a pain because the language doesn't make it convenient) if you have like >10^7 objects. (That's my personal experience from a 2-month project, and I normally don't use Java).
There are if you use language extensions like Packed Objects on the IBM JVM or Object Layouts on Azul.
So just like C, you have C and then GCC C, clang C, ....
Eventually Java 10 will fix this, but for those that like to live on the edge there are already snapshots available.
$time java HelloWorld
Hello, World
real 0m0.071s
user 0m0.053s
sys 0m0.020s
That is a linux vm running in a mba (first run).
In any case, the point that I wanted to make in the parent comment was that the JVM startup time itself was basically fine.
I just checked on my Macbook and a HelloWorld class gives me .13 secs real.
There are work arounds for this (things that reuse jvms and such) but until that is overcome the jvm is largely not appropriate for cli tools that start/stop.
But for other kinds of interactive programs, things with long running sessions and such, it is pretty easy to a) lower that startup time and b) do things that mitigate it to the user.
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.
20:43:44,578 INFO [org.jboss.as] (Controller Boot Thread) WFLYSRV0025: WildFly Full 10.1.0.Final (WildFly Core 2.2.0.Final) started in 6551ms - Started 331 of 577 services (393 services are lazy, passive or on-demand)
Not too shabby IMHO.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.
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.
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.
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.
$ 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!
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.
* 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
[1] https://raw.githubusercontent.com/dotnet/coreclr/master/PATE...
This may be true for the Core CLR specifically, but it's not true of real .NET apps that are being built today. The vast, vast majority are strongly tied to the Windows platform, especially because of the lack of a cross-platform GUI like you mention. As a Wine developer, it's a huge pain in our side because we either have to run the entire .NET virtual machine, which is hard, or depend on Mono, which is by design not completely compatible. This results in really souring my opinion of .NET and .NET applications when compared with win32 applications that do tend to work quite well in Wine.
> 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...
Refactoring, Coding assistance, Navigation & search sections being most important.
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.
If it were to develop today as against raising against time(Apple) then Google would have written their own runtime and everything.
Of course they did. It's not a secret they designed it as a Java clone when the justice ruled they couldn't embrace the original one.
However, they missed something: cross-platformness. So essentially you get a windows only Java platform. That's why not everybody finds it impressive nor are looking forward to commit to using it everywhere (they wouldn't be able, though)
What is the status of this? Will MS be bringing WPF (XAML) to all platforms?
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.
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)
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.But I'd argue that there are very few benefits of JIT that can't be achieved by AOT + PGO. A sound static type system nullifies the need for most of those benefits (like speculative type optimizations and deoptimizations). But it might have the upper hand in cases where profiling can't capture all of the possible optimizable workloads that the binary would see. Databases or other large programs that continuously specialize over the lifecycle of the process. But that is far more niche than most people realize.
I'll half-agree with respect to phones and embedded environments since those are wildly variable and may include extremely low-specification platforms.
But a desktop or laptop? The JVM launches in milliseconds on my desktop and laptop. The monstrous Eclipse IDE launches in about six seconds on my desktop, and about five seconds of that time is Eclipse loading various plugins and what-not, in what looks like a single-threaded manner.
My desktop and laptop can both spin up Undertow and fire up a web-app from a Jar in about two seconds.
I'm fairly sure Eclipse is just using an old clunky CMS garbage collector. I've never tuned it on my desktop or laptop. Maybe Neon is using G1 now. I don't know and don't care because it runs just fine.
Maybe you've done something different with the JVM on desktops and laptops, but in my experience, on desktops and laptops, the JVM behaves more or less the same as it does on servers.
Kids today! Sit down over here, and Grandpa will tell you about the days when a few hundred megabytes was more than your average server's entire storage capacity. Now, in those days you tied an onion to your servers, which was the style at the time...
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.
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.
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?
I don't love Cassandra, but it's not because it's written on the JVM (full disclosure, we roll our own JVM key-value datastore https://github.com/liveramp/hank).
If your random-access keystore is limited by anything except network and disk latency, you have bigger problems.
so what you mean is that, even after throwing facebook scale resources at java.. it is possible for a <10 people team to get 10X performance over java using the features that you mention.
That's a huge loss of face for java IMHO
Naive translations from Java to C++ will normally result in only a small % difference.
But clever rewrites where control of memory locality is leveraged, and SIMD intrinsics are leveraged (either via pragmas to induce it automatically, or by hand), good understanding of compiler settings for given architectures, etc, the differences can get quite large, depending on the problem domain.
Then again, there are ways around some of the performance limitations in the JVM, but it often involves writing very painful coding styles. But you could narrow the gap a bit with that effort. (but if you are going to add effort, maybe just do it is in C++?)
http://www.jcmit.com/diskprice.htm
The numbers we're talking about here just aren't a practical consideration any more.
But the CPU time spent by the dynamic linker resolving thousands upon thousands of symbols? That's actually rather painful.
The Avian JVM can statically link an entire program and widget toolkit with itself and produce a 1mb binary.
It's not that big a deal. The space gets taken up by all the libraries. But then you'd want to compare a JVM against e.g. /usr/lib on a fresh Linux install ...
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.
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.
But I have to agree w/ others that after using golang, where an equivalent web app would run in <50Mi of RAM with far better tail latencies, the memory cost of the JVM feels very large.
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.
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.
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.
You could if you really wanted to just auto-convert Maven Central to DEBs. The metadata is there. The problem is that "dependency hell" would then visit you in the same way it does for Linux apps. Upgrading libraries is something that should either be done by developers, or by OS vendors very carefully, not by having some random part time packager run a script and push a new version that immediately propagates down to everyone else without any app-compat testing.
$ 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.
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.
cc1 is 20MB over here. gold is 5MB. Dynamic libraries it depends on (gmp & family, isl) weigh about 4MB. All-in-all the programs required to compile even a simple C program come out around ~32MB.
Clang is much bigger. Clang 3.8 is 59MB (I think that includes the preprocessor though, but GNU's CPP is only around 1MB (which still seems huge for a preprocessor)).
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
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.
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
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.
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.
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.
This is exactly the kind of development culture that produces heavyweight, unresponsive tools.
If it wasn't for the pressure of game developers, the NDK wouldn't even exist.
Remember Brillo? It was supposed to be like Android, but using C++ frameworks instead, as presented at Linux Embedded 2015 conference.
Guess what, when it got recently re-branded as Android Things, it switched to the Java Frameworks instead and it doesn't even allow for the NDK, with the user space device drivers being written in Java.
Is this cognitive dissonance? Dishonesty? I don't understand.
Some people don't think that those massive 16/32G MBPs etc with SSDs are not available to everyone.
You should ensure both memory modules are same size (say, 4 GB or 8 GB), otherwise performance can suffer noticeably.
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.
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.
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?
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.
Fortunately I typically only need to restart it when switching branches.
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.
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.
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.
That's a many-hundreds-of-MB Spring enterprise behemoth of a Java server.
Have you ever tried running Java on a micro?
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.
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/m9QxxTIL. Why are those XX flags?
If you want something light like Clojure and don't need any Java libs, try 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.
Same thing with Clojure. It basically bootstraps the entire Clojure environment on each process start. The JVM itself starts up in tens of milliseconds.
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.
Load wasn't exactly high, but it worked absolutely fine.
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.
- 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.
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.
I find this similar to discussions about boot time. It doesn't matter -- I reboot my computer once a month, if even that.
More power to them.
http://penguindreams.org/tutorial/embed-tomcat-in-your-appli...
..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.
Well, whoever does this is Doing It Wrong.