Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

Why did the team at LMAX design the LMAX Disruptor in Java but all their design points to minimizing GC use? If one does not want to have GC run then why use a garbage collected language?

Their optimizations, the level of hardware knowledge and the thought they put are just awesome but why Java?

I'm not against Java or anything, but why a GC language? Why not use something like D or any other language without GC but allows efficient code? Is it that the team is most familiar with Java or does Java possess some unique advantage that I am not seeing?

Say they develop it using D with manual memory management, what would be the difference? They would have to think low level (which they already are), but they can squeeze the best performance out of the system as it's native.

share|improve this question
4  
I know very little about this project, but it seems it is some kind of framework that others can build upon. And if you manage to write that in Java (and allow others to code in Java and reap the benefits), then you'll have a MUCH larger "customer base" than if you'd have written it in D. –  Joachim Sauer Dec 23 '13 at 14:11
5  
@kadaj: it doesn't really matter if the consumer is public or internal: if you make it accessible in a widely-known language, it will be more useful, even for internal development. If you start your (hypothetical) argument with: "Assume that everyone knows D as well as they know Java, ...", then you're probably missing something. –  Joachim Sauer Dec 23 '13 at 14:15
3  
Some people like using hammers for all sorts of problems. Got a rough edge you want planing off, bash it with your hammer until its smooth. Got a screw you need driven in, bash it with a hammer until its in. Got a delicate ornament you need sanding down, bash it with a hammer and then blame the ornament for "sucking". C or C++ would have been a better choice than D, if only for the existing knowledge base. Not sure why you even brought up D as an example TBH. –  gbjbaanb Dec 23 '13 at 14:58
1  
@gbjbaanb I mentioned D because it provides garbage collection (in cases where high level abstractions are necessary and fiddling with memory is too hard for the brain) but also allows manual memory management with C style malloc and free. D is sort of like Objective-C with ARC (no real GC) but better than that. But yeah, C/C++ would fit the bill. –  kadaj Dec 23 '13 at 15:16
1  
@kadaj I see you've been getting some flak here for bringing up D but I want to say I'm disappointed in the tone others are using and lay out why I think D is central to the question at hand. While D is indeed not widely used, D provides some high-level constructs that I might expect to find in say Java or C# but not in (at least old-style) C++. It still provides for mixing managed and unmanaged - which is just about the only language I know to do that! So D is not just a pet choice, but rather one that has goals coinciding with the original questions around GC. –  J Trana Dec 24 '13 at 6:46
show 8 more comments

4 Answers

up vote 9 down vote accepted

Because there is a huge difference between optimizing the performance and turning off completely a safety

By reducing the number of GC, their framework is more responsive and can run (presumably) quicker. Now, optimizing for the garbage collector don't mean they don't ever do a garbage collection. It just mean they do it less often, and when they do it, it run really fast. Those kind of optimization include :

  1. Minimizing the number of object that move to a survivor space (i.e that survived at least one garbage collection) by using small throw-away objects. Object that moved to the survivor space are harder to collect and a garbage collection here sometime imply freezing the whole JVM.
  2. Don't allocate too many objects to begin with. This can backfire if you're not careful, as the young generation objects are super cheap to allocate and collect.
  3. Ensure that new object point to old one (and not the other way around) so that the young object are easy to collect, since there is no reference to them that will cause them to be kept

When you tune out the performance, you usually tune some very specific "hot spot" while ignoring code that don't run often. If you do that in Java, you can let the garbage collector still take care of those dark corner (since it won't make a lot of difference) while optimizing very carefully for area that run in a tight loop. So you can choose where you optimize and where you don't, and you can thus focus your effort where it matter.


Now, if you turn off completely garbage collection, then you can't choose. You must manually dispose of every object, ever. That method get called at most once per day? In Java, you can let it be, as its performance impact is negligible (it may be OK to let a full GC occur every month). In C++, you are still leaking resource, so you must take care even of that obscure method. So you must pay the price for resource management in every, single, part of your application, while in Java you can focus.


But it get worse.

What if you have a bug, let say in a dark corner of your application that is only accessed on Monday on a full moon? Java have strong safety guarantee. There is little to no "undefined behavior". If you use something wrong, an Exception is thrown, your program stop, and no data corruption occur. So you are pretty sure that nothing wrong can happen without you noticing.

But in something like D, you can have a bad pointer access, or a buffer overflow, and you can corrupt your memory, but your program won't know (you turned the safety off, remember?) and will keep running with its incorrect data, and do some pretty nasty things and corrupt your data, and you don't know, and as more corruption happen, your data get more and more wrong, and then suddenly it break, and it was in a life critical application, and some error happened in the computation of a rocket, and so it doesn't work, and the rocket explode, and someone die, and your company is in the front page of every newspaper and your boss point its finger to you saying "You are the engineer that suggested we used D to optimize performance, how come you didn't think of safety? ". And it is your fault. You killed those people with your foolish attempt at performance.


OK, ok, most of the time it is much less dramatic than that. But even a business critical application or just a GPS app or, let say, a government healthcare website can yield some pretty negative consequence if you have bugs. Using a language that either prevent them completely or fail-fast when they happen is usually a very good idea.

There is a cost to turning off a safety. Going native doesn't always make sense. Sometime it is much simpler and safer to just optimize a bit a safe language that to go all in for a language where you can shoot yourself in the foot big-time. Correctness and safety in a lot of case trump the few nano second you would have scrapped by eliminating the GC completely. Disruptor can be used in those situation, so I think LMAX-Exchange made the right call.

EDIT

But what about D in particular? You do have a GC if you want for the dark corners, and the SafeD subset (that I didn't know of before the edit) remove undefined behavior (if you remember to use it!).

Well in that case its a simple question of maturity. The Java ecosystem is full of well-written tool and mature libraries (better for development). Much more developers know Java than D (better for maintenance). Going for a new and not-so popular language for something as critical as a financial application would not have been a good idea. With less-known language, if you have a problem, few can help you, and the libraries you find tend to have more bugs since they were exposed to less people.

So my last point still hold: if you want to avoid problems with dire consequences, stick with safe choices. At this point in the life of D, its customer are the little start-ups ready to take crazy risks. If a problem can cost millions, you are better staying further in the innovation bell curve.

share|improve this answer
1  
The original post specifically calls out D. There is actually quite a big difference between C++ and D with regards to granularity of choice. Even if you do choose to go full-managed in the SafeD subset, I think you get quite a bit more control over certain aspects of collection and timing (enable/disable,collect,minimize). Check out Digital Mars' strategies for memory management! –  J Trana Dec 24 '13 at 7:27
    
lmax deliberately side step some of the safety Java provides –  James Dec 24 '13 at 16:33
add comment

They would have to think low level

Above makes half of the answer you're looking for. You can find another half to complete the reasoning no farther than in LMAX blog:

While very efficient, it can lead to a number of errors as it is very easy to screw up...

As admitted by LMAX developers, code like that might be quite difficult to develop, understand and debug - even in Java. Going lower level further than where they are now will only exacerbate this problem, as pointed in Wikipedia article on low level programming languages:

A program written in a low-level language can be made to run very quickly, and with a very small memory footprint; an equivalent program in a high-level language will be more heavyweight. Low-level languages are simple, but are considered difficult to use, due to the numerous technical details which must be remembered.

By comparison, a high-level programming language isolates the execution semantics of a computer architecture from the specification of the program, which simplifies development...

share|improve this answer
add comment

LMAX is a High Performance Inter-Thread Messaging Library.

To be useful someone else has to write the code to get each thread to do useful work. Given that the code is most likely to be in Java or C# and then there are very few chooses of language that interface well with them.

Using C or C++ is not a good option unless you wish to limit your users to a single OS, as there is no threading model defined in them.

Java is the standard for a lot of software development these days, so unless you have a good reason otherwise, it tends to be the best choose. (When in Rome do as the Romans…)

Writing High Performance software in Java (or C#) is often done to prove a point…

share|improve this answer
1  
The new C++11 standard supports multithreading... –  Casey Dec 23 '13 at 16:12
    
@Casey, and how many real world C++ compilers use it? And how much do these compilers cost. Maybe in 20 years times it will be useful, until then you can't depend on it. –  Ian Dec 23 '13 at 16:18
    
Disruptor uses sun.misc.Unsafe quite a bit which shows that you can't really write low latency code in Java without dipping your toe into C land –  James Dec 24 '13 at 16:24
    
Gcc supports C++ threads and it's free –  James Dec 24 '13 at 16:25
add comment

It seems the reason it's written in Java is that they have Java expertise in-house and it was probably written (although it's still in active development) before C++ got its act together with C++0x/11.

Their code is really only Java by name, they use sun.misc.Unsafe quite a bit which kind of defeats the point of Java and the safety is supposedly gives. I have written a C++ port of the Disruptor and it outperforms the Java code they ship (I did not spend a lot of time tuning the JVM).

That said, the principles that the disruptor follows are not language specific, e.g. Don't expect low latency C++ code that allocs or frees from the heap.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.