Hacker News new | ask | show | jobs
by smanek 5183 days ago
I think Java is a pretty bad language, but most of your points are provably wrong. You're either grossly misinformed (some of what you say was true about a decade ago, but hasn't been since around the 1.5 release in ~'04) or purposefully spreading lies.

You're factually wrong about the open-source thing: the primary impl of Java is open source (http://hg.openjdk.java.net/jdk7u/jdk7u). Sure, some impls like Azul might not be - but that's the joy of an Open language with a real spec, anyone can write an impl under any license they choose.

The claim that Objects have 'too much' overhead is subjective - but also basically wrong. Generally Objects in Java have 8 bytes of straight book-keeping overhead, plus padding to get the size of the fields to the nearest multiple of 8 bytes. That's expensive relative to C, but cheap compared to almost any other object oriented, GCd language (and can often be avoided via primitives, escape analysis, etc). For reference, CPython (the main Python impl) has ~30 bytes of overhead on an Int between tag bits, book keeping, etc last time I investigated.

How do you think the Java concurrency model is flawed? Almost any concurrency model I can think of, from Erlang-style message passing (see: Akka) to the new Fork/Join framework can be implemented in Java since its concurrency primitives are complete. I've even done basic impls of STM on AtomicRefs. Frankly, Java has one of the better defined and fine-grained concurrency models I know of. C++ just got a well-defined memory model in the '11 standard IIRC (vs '04 for the JVM).

I'm with you on the functional programming thing - syntax on anonymous inner classes and a lack of type inference make it way too verbose. But it's (largely) fixed via Project Lambda in Java 8. And, in the meantime, there are plenty of great JVM languages (Scala, Clojure, etc) with better support.

2 comments

The claim that Objects have 'too much' overhead is subjective - but also basically wrong.

I don't know if this is what the author originally intended, but as a most-of-the-time .NET programmer, I do see one glaring flaw to Java that falls along these lines, and which I believe is inherited from the JVM (I've heard of it being a problem for people trying to write a C# compiler that targets the JVM): There's no concept of a user defined pass-by-value type. There are only primitive types and reference types (i.e., objects).

This does create some overhead. It means that for any instance of a user-defined type you have to use additional resources in two ways which may be unnecessary: First, it goes on the heap, so it invariably adds to the garbage collector's workload. Second, it's always going to be internally referenced indirectly via a pointer. That's an extra 4-8 bytes that could be significant overhead for a sufficiently small type - say, a struct that represents an RGBA value as four separate bytes. That's also poorer locality of reference, in a way that I suspect could bite when you're dealing with large collections of small elements.

> There's no concept of a user defined pass-by-value type.

Everything is pass-by-value, but I understand what I mean.

> Second paragraph ...

Yes, it all sounds legit. But in reality, it is often quite different and after the JIT compiler ran not a single object allocation or dereference is left. It's not like JVM engineers are stupid, you know. :-)

Hm... I'm not trying to argue with you, you're right that I only have a superficial overview of the Java/JVM/J2EE ecosystem, but I will try to elaborate on the points of my original post, which was rather sparse, I admit.

As I read Wikipedia, HotSpot is opensource. I'm not sure if that includes the best JIT compiler (what the JVM is known for) as well, or if that's still closed/proprietary, but I'd be pleasantly surprised if it's open source as well. Still, we have the patents issue, i.e. the current legal battle between Google and Oracle. Releasing the source but suing anyone who uses it is not the way to do open source, IMGO (true, the source was release by Sun, and Oracle is the one who's suing, but still).

I believe that a general purpose programming language (suitable for business applications) has to be able to perform as well as C for heavily optimized code. What I mean is that you have to be able to write algorithms that run very fast. You can probably do that with C# (supports unboxed structs) and maybe even Objective-C (supports MemoryPools, and method lookup caching), but not Java (AFAIK). Sure, you can always link to external C libraries, but then you have to face dependency hell and portability issues.

The issue that I see with Java's concurrency model is not that it is not powerful enough, but that it is too powerful. It allows synchronization on any heap-allocated object, which probably has a lot of overhead (used to be performance overhead, but HotSpot was heavily optimized for that, so after a lot of programmer-hours overhead, the performance overhead was lowered). However, I think that this kind of threading model is not scalable to massively parallel/distributed environments. Synchronization/sharing will have to be limited, e.g. as in Erlang/WebWorkers/Rust, using GCD in Objective-C, using MVar (Haskell) or transactional variables (Clojure). Java probably can never do that, without sacrificing backwards compatibility.

Lack of support for functional programming was meant more on the JVM level. There are no tail calls, no fast object allocation, no true polymorphism, and I'm guessing that since closures have to be represented as objects, they are not particularly cheap.

Hotspot is the most commonly used JVM impl I was referring to. Last I looked into it (probably a year ago), some of the graphics libraries it includes weren't open source - but everything important (including the JIT) is.

The patent issues are regarding Dalvik AFAIK, so I don't see how it's relevant to this discussion ... (although, from what I've heard, it seems like Oracle's being a jerk ...)

If you think that a general purpose language has to be able perform as well as C without calling native code (JNI, FFI, etc), I guess I'd have to agree Java isn't 'general purpose' . But I'd contend neither are Python, Ruby, Erlang, Javascript, etc under that definition. Therefore, that's probably not the right definition, since it excludes most general purpose languages ;-)

Being able to synchronize on any object is actually really efficiently implemented (8 bytes of Object overhead total, neat optimizations like biased locking, etc). And, if you don't want to share state between threads, Java can do pretty clean actors/message passing (http://doc.akka.io/docs/akka/2.0/java/untyped-actors.html) or transactional variables (AtomicRefs are built in). Java concurrency does give you the ability to shoot yourself in the foot if you use it wrong, but so will any sufficiently powerful tool.

Re the JVMs support for FP:

- JVM7 added an InvokeDynamic instruction which I believe addresses your polymorphism concerns.

- It sucks that there isn't a bytecode instruction to allow TCO. But, in practice, many JVM languages will convert recursion to iteration at compile time with constructs like http://clojure.org/special_forms#Special%20Forms--(recur%20e...

- What do you mean by 'fast object allocation'? I'm not familiar with the term ... Creating objects is fairly fast in Java though. A quick test suggests I can alloc around 200 million objects per second on the heap once the code path is JIT'd on my laptop. Incidentally, it's surprisingly tricky to fool the JVMs escape analysis and force a heap (not stack) allocation, without introducing too much extra work in a microbenchmark ;-).

- AFAIK, you're right that closures require an object allocation - but how else would you do it? When I was writing Common Lisp, we had to avoid creating closures in tight loops for the same reason

I checked (FMI, For My Info, the non-open pieces are the launcher, Iced Trea vs. javaWS, and fonts which are replaced by FreeType in OpenJDK

http://www.reddit.com/r/scala/comments/m1dks/poor_performanc...

Openjdk contains hotspot, and is now the reference implementation of the Java SE Platform. There are proprietary JVMs as well, but if you want to use an open source implementation you can and it is the reference, so compatible with the standard.
- Yes, HotSpot is “the real” thing and includes the best Oracle has. There is a JVM implementation from Azul too, which people consider to be excellent.

- The case between Oracle and Google is not related to the code released by Sun/Oracle.

- You can write heavily optimized code in Java that is as fast or faster than C, without using escape hatches.

- There is no overhead for things you don't use (synchronization).

- The JVM has probably the fastest general-purpose implementation for concurrency primitives for high-level languages. See for example: http://letitcrash.com/post/20397701710/50-million-messages-p...

- The lack of tail calls is very annoying. The rest just works. -