Sunday, August 10, 2008

Benchmarking the cost of dynamic proxies

I needed to quickly compare the cost of dynamic proxies versus direct access to objects, and also position it in relation to RMI. In theory we know that they add overhead, but how much? I just wanted more precise arguments to reinforce a rather obvious statement: “Dynamic proxies are not that bad. Take RMI for example...” :)

I could not find exact and up to date info saying that RMI is X times slower than direct method calls, nor dynamic proxies. In this link they’ve said that RMI is at least 1000 times slower than local calls. Since that appears to be some info from 2001, I imagine that we’ve had some nice optimizations in JVMs in the last 7 years.

I’ve changed a benchmark code that has been used in my lab, so I could have an approximate value of each method call in different approaches. This post (which actually points to here) that I’ve just read this Sunday helped me a lot in adapting the code.

My benchmark consisted of calling a million times a method in a given object which implements the tested "dummy" interface. The method was void with no parameters, and the implementation had just one line of code assigning an integer variable. The idea was to get the closest possible to the actual invocation time, with the minimum possible for method execution time.

I’ve executed the benchmark a few times and I’ve always got the same minimum values for direct calls and dynamic proxy, respectively. However the minimum time for RMI calls varied a lot.

Dynamic proxies: 1.63 times slower than direct calls, which is not bad.
RMI calls: At least 200 times slower.

For info, here is my not so performing platform:
JVM: Sun Hotspot/JRE 1.6.0 07.
OS: Windows XP SP2.
Hardware: Pentium 1.7 GHz 1GB RAM

The cost of dynamic proxies surprised me. This article from developerWorks shows similar conclusions. I thought they would be more expensive. However, we are talking about a minimal overhead level here, as in actual usages of proxies we usually add more code for decoration, verifications, etc which would obviously lead to more than the 1.63 times that I’ve measured. Well, this info provided here cannot considered sufficient as more tests would need to be performed in order to be more precise.

Sunday, July 20, 2008

JSR 296 in coma ?

I’ve been checking the upcoming features of Java 7 and found a cool detailed list here. Also, some Java One 2008 slides from Danny Coward’s presentation show a little on that too.

Among the JSRs mentioned in the first link, I already had checked some stuff from JSRs 277, 294, concerning Java Modules, JSR 284, concerning resource consumption and JSRs 295, 296 and 303 concerning Swing.

I’ve known these swing-related JSRs since, more or less, they became available as JSRs. I had special interest on them at the time because I was working in a project where we needed a product built on top of a Rich Client Platform, to enable the development of plugins from third parties. The idea was to have a simple and pluggable structure.

For us, Eclipse RCP was overkill so was the Netbeans platform. Spring RCP was in its initial stages. We’ve decided to go from scratch, using OSGi as the base for a pluggable architecture, and build our own straightforward RCP. The JSR 296 (Swing Application Framework) proposes most of what we needed (and developed) as a Swing foundation for our RCP:

  • Resource management for i18n
  • Task services/monitoring
  • Storage for session state
  • Events/actions framework
  • Managed application exiting (exit listeners), startup, shutdown

I can't say that this is a PCP (Poor Client Platorm). Maybe an ARCP (Almost Rich Client Platform). But, as I said, it does most of what we needed at that time. And I believe there are hundreds or thousands of other applications that don't need all the heavy richness provided by the RCPs.

So I decided to take a look at JSR 296 (Swing Application Framework) to see what they have for us so far. I’ve downloaded it from the project site. (You should also need to download the SwingWorker since they do not use the SwingWorker delivered with Java 6)

This tutorial has good examples concerning the features of the JSR 296, like the magic stuff for saving session state (components dimensioning, positioning, etc):

//The non-qualified getters below are inherited from the SingleFrameApplication class
//
//Saving session State
getContext().getSessionStorage().save(getMainFrame(), sessionFile);
...
//Restoring session State
getContext().getSessionStorage().restore(getMainFrame(), sessionFile);

Lots of weeks of modelling and coding can be saved by using that framework.

There was a weird thing about the last available version: it was from November 2007. It seems that it is not evolving anymore. I’ve read a few months ago in blogs that I don’t recall, that some senior engineers from the Swing team were leaving Sun Microsystems. I could find this blog entry mentioning some of them.

The guys that took care of JSR 296 (Hans Muller) and 295 (Scott Violet) are gone. However, I think that there are no worries with JSR 295 and 303 which are just “standardizing” the concepts used in JGoodies by Karsten Lentz, who is a member of both expert groups. But the JSR 296 is apparently a home grown implementation from Sun. The guy that was handling that is gone, and there are no new versions for 8 months.

Weird… It appears that the project is in some sort of "coma".

Don’t know if it will make it until Java 7

Sunday, July 6, 2008

Heap snapshot analysis and objects with different class versions

I’ve been working lately on the detection of a particular problem, called stale references, that may happen on OSGi based applications. It is a consequence of bad OSGi programming practices that may lead to memory retention and the utilization of inconsistent objects.

As a part of the diagnosis process I need to analyze heap snapshots to find the referrers of services that have been unregistered. I’ve found some interesting stuff (at least for me) concerning memory inspection and classloading. Each module (bundle) in OSGi is provided with its own class loader instance. If you replace (update) a module during runtime, it will basically stop, refresh and restart; and get a new class loader. Objects and classes from the previous class loader must not be referenced anymore, and that previous CL is supposed to be “discarded” and GC’d.

In our custom tool I was seeing that objects from “discarded” class loaders were still being referenced by other modules. However, when I used JHat (either embedded or standalone) to inspect the heap snapshots by performing queries like “select x from com.foo.TheClassOfTheReferencedObject” the result set listed only one object instance (from the running module) when I was supposed to get two instances (one loaded by the old class loader and other by the new one).

I thought my tracking code was falsely accusing the service object from the old bundle version. After patiently and manually (maybe “stupidly”) verifying each class loader instance, I found the two different class loaders that referred to the same bundle ID, and could also found the “lost” object.

After a few weeks I’ve tried to track the same problem with the heap inspection provided in the VisualVM. It worked like a charm! I could see all object instances of the same class name, no matter what class loader provided the object class. It does not have advanced queries like JHat, but in this case I only needed a filter to find the class instances that interest me.

It’s a pity. JHat has powerful queries to analyze heap snapshots, but it can’t deal clearly with the same class names loaded by different class loaders (i.e. different versions of the same class). VisualVM has much more limited power that JHat, but allows to see attribute values, referrers and referring trees just like JHat. In addition, VisualVM deals with no problem with classes carrying the same name but loaded by different class loaders, and that what’s more interesting for me, at least for now.

Monday, June 16, 2008

How can we developers (not the companies) do off-shore jobs ?

Recently (actually just 40 minutes ago) I got an “almost certain” temporary home-office contract refused because I am overseas.
Huh ?

I’ll explain it… But skip to (2) if you’re in a hurry…

(1) The company is located in Brazil, and some people who know my job (and apparently trust on it) wanted to hire me for a temporary home-office job in that company. No development services with them so far, but as a freelance trainer last year I’ve even taught Java classes in this company which is also a faculty and tech training school, so I’m not a complete stranger for them.

I've quit my job 10 months ago and came to France to enroll in a computer science master’s degree. Ok so far. That's my choice. After knowing that some friends had done home-office for them, and since I was about to take summer vacations I’ve contacted them one month ago and said “hey if you need somebody for home-office development I’m here”.

Before leaving I left a legal representative in Brazil who can sign papers in my name, open bank accounts, etc. I’ve informed the company that I was going to be able to give legal receipts, invoices or whatever, which was what they have asked for.

But their legal department said NO…

(2) To make this story shorter:

  • The receipt/invoice would be issued by the town hall of my home city in Brazil (this is the type of receipt they asked for)
  • The money would be deposited in my bank account in Brazil
  • The job was going to be performed by a brazilian citizen with brazilian documents who would sign a contract with them, but with a TEMPORARY address in France and a PERMANENT address in Brazil.

However, as I am not residing in the country, the legal department refused to issue the temporary contract.

I have no clue how to deal with such situation. Neither these guys who contacted me have. They had good intention but the big guys said no…

My question is: how to deal with such issues related to off-shore jobs? Usually companies are hired to do off-shore. But what about people? Developers like me, like you.
Does anybody have ever faced similar situations?

Monday, June 2, 2008

OSGi Community Event

The second annual OSGi Community Event will take place next week (10-11 June), in Berlin, Germany. The event will have presentations and demos concerning both business and research projects.

It is a little expensive (550 euros for non-members) but it is a good opportunity to business and research personnel gather together and exchange ideas and present results on OSGi technology usage.

Sunday, May 25, 2008

More on the "OSGi hype"

I’ve seen more and more people talking about OSGi lately. Some are saying that we are going through “OSGi hype”…

Well, I’ll talk about the OSGi hype here too :)

OSGi is being around for almost ten years. Maybe it gained (more) momentum after Eclipse adopting it since version 3. I’m not sure, I have no "authority" to say that. That's just what I think as an outsider.

A non-exhaustive list of OSGi advantages: no more classpath hell, modules life cycle, dynamic updates with no application reboots, package visibility, decoupling through services.

Several important organizations are seeing OSGi’s value and are investing on it. This guy posted a list of applications using OSGi. We can add Apache Sling , Apache ServiceMix and Project Fuji to that list too, as well as Glassfish. I've worked as part of the team that developed a now extinct product built on top of OSGi. There must be a lot of other not so popular stuff built with OSGi.

Maybe some recent events caused all this hype:

  • JOnAS 5 released as the first (I guess it was the first one) JEE application server to run on top of OSGi.
  • Recently we’ve seen Glassfish using it.
  • JBoss is talking about OSGi.
  • BEA (now Oracle) is using OSGi in its microservice architecture.

I guess OSGi has become the de facto module system for Java. It seems that JSR 277 has a risk of falling into oblivion when it becomes released if it does not converge with OSGi. Since so many important announcements about OSGi adoption are taking place, we are seeing this “OSGi hype”.

In my opinion, this is not hype. It is industry evolution. But those that still do not get it may see it only as hype.

Technology hypes may sometimes lead to some naïve decisions like “let’s use it because it’s a cool trend and everybody is using it. It's a new trend”. Maybe that was a naïve example too...
Before choosing to use stuff like OSGi try to evaluate if it fits your needs. Get to know it better. Maybe taking a look at the docs in the OSGi alliance website or looking for tutorials. Decisions like this involve the architecture of your project.

Whoever tries to use OSGi must be careful with the sometimes steep learning curve. Try to take advantage of existing component models (OSGi declarative services, Service Binder, Spring DM, iPOJO) that handle hard dynamic aspects, service location, dependency injection, and do all the dynamic voodoo magic. There was a time when all that stuff needed to be made by hand. You don’t need to do that anymore.

There is some stuff that is painful in the beginning like “bundlizing” a jar. But constructing an OSGi compliant manifest may be simplified by automated stuff like a bundle plugin for maven. Well, there is plenty of stuff (like here) to minimize efforts concerning OSGi development.

I'm away from the market for almost a year and started (or continued, if you will) to do research that involves OSGi. Each time I see news about its adoption in industry I get even more motivated about my choice.

Even if you don’t buy the idea or if it is useless for you, it is worth taking a look. OSGi is not just a buzzword. Try to use it not because it is hype, check its benefits first.

Wednesday, May 14, 2008

Do you know weak references? Have you ever used them?

I’ve been using a lot of weak references lately. A couple of years ago I’ve read a blog entry that said that a lot of experienced Java developers did not know what they were. I’m glad I already knew it at the time I’ve read that :)

I won’t go into details of weak references. I’ll just say that an object is not prevented to be garbage collected if it only has weak references pointing to it. You can get a nice overview here.

In my current project I’m tracking garbage collection of special types of objects by using weak references. Maybe in another post I’ll provide more info on that.

Throughout my career I’ve used that nice resource of Java a few times. The most important ones that I can remember are:

  • Weak Listeners
  • Memory Sensitive Caches

Weak Listeners

Memory leaks are a painful problem that sometimes we don’t have a clue how to find them. I’ve worked in a desktop project where we had lots of instantiations of GUI panels, models, etc. That implied in a bunch of model listeners, property listeners, and so forth. We had a major memory leak due to a simple problem in most of the panels: objects from each created panel were being added as a listener of the model, but after the panel was discarded they did not remove themselves from the listeners list of the model. So, they kept being reference by the listeners list on the model and could not be garbage collected.

A naïve example tries to illustrate that:

public void setActivePanel() {
MyPanel thePanel = new MyPanel();
ApplicationModel.getInstance().addXYZListener(thePanel);
this.activePanel = thePanel;
}

public void releaseActivePanel() {
this.activePanel = null;
this.clearSelection();
}

One solution was to provide a way to unsubscribe "thePanel" from the XYZListener list:

public void releaseActivePanel() {
ApplicationModel.getInstance().addXYZListener(this.activePanel);
this.activePanel = null;
this.clearSelection();
}

But.... you could also use weak references. They would avoid such problems. At the time I found good stuff that I’ve used as a reference.

The only issue that I see in his solution is that we may have sometimes a bunch of empty WeakPropertyChangeListeners (pointing to null) when the referred object is GC’d. He provides a lazy approach for clean up. However, if you use your own ReferenceQueue you can provide a thread that once in a while polls the queue and does the sweeping of listener lists. Or also you can use a WeakHashMap which does the dirty work of clean up.

Memory sensitive caches

There are several caching strategies (e.g. LRU, MRU) but this one is very simple. It caches everything, but when the system runs out of memory the cache is cleaned up.

Depending on the memory footprint of your system this strategy may be useless and your cache will not work really well.

This memory sensitive cache relies on SoftReferences. They are special types of WeakReference which hang around for a while.

The following class is not an optimal implementation of a cache, but it works…

public class ImageCache {
private HashMap<String, SoftReference<ImageIcon>> map = new HashMap<String, SoftReference<ImageIcon>>();
private static final String IMAGE_FOLDER = "/images/";

public ImageIcon getImage(String imageFile) {
ImageIcon icon = null;
if (map.containsKey(imageFile)) {
icon = map.get(imageFile).get();
if (icon == null) {
icon = cacheImage(imageFile);
}
} else {
icon = cacheImage(imageFile);
}
return icon;
}
private ImageIcon cacheImage(String imageFile) {
ImageIcon icon = new ImageIcon(this.getClass().getResource(
imageFile));
map.put(imageFile, new SoftReference<ImageIcon>(icon));
return icon;
}
}
Another cool stuff that can be done (although I've never done it in a "real life" project as I did with the other stuff) is to provide an alternative way to finalization using PhantomReferences. You can use them combined with a ReferenceQueue to provide your own finalization mechanism avoiding the error-prone finalize method. You could write your own finalizer thread :)

There is a good reference here.

I guess that it for the moment.