Monday, October 20, 2008

Closures

As an old Smalltalker the addition of closures to the Java language sounds awfully good. Not a coding day goes by or I have a tinge of frustration when I have to do extraneous typing that would have been unnecessary in Smalltalk, where closure are the bread and butter of programming. So you would expect that I would be thrilled. However, I am having some reservations because of a very non-functional aspect of the two main proposals (BGCA and FCM): class loading. Let me elaborate.

About two years ago I played with Groovy and very much liked the builder pattern. With the builder pattern you can create code that looks like HTML but has access to all of Groovy's extensive features. This was great! A friend and I created some examples from an existing web application and it looked wonderful. Unfortunately, it turned out that there was a huge penalty because every closure was compiled into a class. With thousands of closures, class loading quickly became a performance issue. Just imagine heapspaces of many gigabytes (most of them strings, perm spaces that grow to hundreds of megabytes or more).

Knowing closures, I am convinced that untold developers will enthusiastically use them and also create thousands of closures in an average application. This will add a significantly to the number of classes in an application. And though I am the first to admit that class loading is fast, (and even faster in OSGi), the cost is absolutely not zero. And this worries me because when I look at the big vendors in the J2EE application server market than I know that their code bases are already creaking at the seams. You would be impressed if you knew the tricks that were being played to keep the system from grinding to a halt.

Until now, we have been more or less saved by computers becoming faster and faster, and disks growing bigger and bigger. However, the news I read today tells me those good days are over. Yes, we will get more and more cores, but each core will become slower. Though you can do some parallelization of class loading, there are many serial bottlenecks that are unavoidable.

The worst thing of all is that I do not fully understand why the proposals could not compile to methods. Methods are much cheaper than classes because the overhead of class loading is mitigated over all the methods in a class.

To make one thing clear, OSGi class loading is much more efficient than other class loading models due to its network nature instead of hierachy. An OSGi class loader knows authoritively who to consult for a class. OSGi based systems will have the least number of problems.

I do realize that it is usually not a good idea to let a high level design be influenced by low level details like class loading. However, I am ringing the alarm bell in this case. I am seeing too many problems at the bottom of the system that are caused by the people at the top that seem oblivious of the problems they are causing downstream. When you share resources, which is what you do in an application server, you must accept some responsibility for the commons or in the end face reduced performance.

Both JRuby and Groovy now compile closures to methods. Hey! If the dynamic guys can do it, then shouldn't we be able to do this as well in Java?

Peter Kriens

9 comments:

  1. Peter, both the links point to the same thing: the FCM proposal.

    It's interesting that making Java yet more complex will actually make it simpler for users...

    ReplyDelete
  2. As co-author of FCM closures, I would be quite happy to see our proposal compile to methods where appropriate. For me, the main point is to get the semantics right, particularly wrt return.

    ReplyDelete
  3. Call me a hopeless idealist but surely this in an implementation problem rather than a fundamental flaw with the specifications of either BGGA or FCM?

    Also since this is a Java 7 change, there should be the opportunity for whatever VM changes might be necessary to support the Java language changes (ao long as those changes are made such that they are compatible with JSR 291!).

    ReplyDelete
  4. An implementation based on method handles would be interesting.

    The alternative would be to fix anonymous inner classes so that they're not so wasteful. This would benefit existing systems too.

    Ismael

    ReplyDelete
  5. It'll be interesting to see if Closures will even make it into Java 7, see for example Alex Miller's predictions: http://tech.puredanger.com/2008/08/02/java7-prediction-update/

    I wouldn't be surprised if Java (the language) became less important over time, but am hoping that Java (the VM) will stay and remain important for a long time to come. Which means that language issues are not as important as issues of JVM mechanics, such as being able to efficiently implement Closures. If Groovy and JRuby are happy with the current JVM capabilities, then that's a very good sign.

    ReplyDelete
  6. Boris, I don't think Groovy and JRuby are happy with the JVM as it is, but the improvements in the MLVM should make them happier. Members of both projects have been contributing to the design and implementation discussions. Part of the MLVM work is being standardised through the invokedynamic JSR so it will not be restricted to HotSpot.

    ReplyDelete
  7. Ed: thanks, fixed it.

    Neil: When I look at the proposals the inner classes seem an intrinsic part of their specifications. It looks like the Generic Java type system lacks the constructs to handle the type constraints that are needed for generically typing methods. As said in the blog, dynamic languages do not have this problem so it is straightforward to compile to methods.

    I wish it was an implementation detail but combined with my Groovy experience and what I see happening in app server land I think we are heading for a future crash if closures are compiled to classes due to the large number of closures that will appear and the incredible number of apps people nowadays seem to run on a single VM ...

    I hope I am wrong, but I think it is something to consider. As stated, I think we are running out of faster processors ...

    ReplyDelete
  8. As far as I know, Groovy closures always compile down to classes.

    ReplyDelete
  9. At the time I played with it they did and I complained about this. The JRuby guys weighted in and explained how they compiled to methods. I recall reading they then decided to go to methods in the next major release, but I can't find any real reference except my original post: http://markmail.org/message/edyinfu62exrnexi

    Then again, I did not spent a lot of time searching ...

    Kind regards,

    Peter Kriens

    ReplyDelete