November 6, 2008

The cost of the 64bit JVM

Running out of heap is never fun, and as applications grow, both in terms of usage and size, this has become a problem for many companies hosting big applications. A number of years ago, when EM64T/AMD64/x86-64 (or whatever you want to call it)-capable servers entered the ring, the most common way to overcome the 1,n to 2,n GB limit (depending on the OS) of the 32bit JVM was to install a 64bit JVM.

The newly gained nirvana, however, was short-lived. We saw the applications consume a lot more heap than they ever did before and still, we were running out of memory. The reason for this is quite simple: Pointers were now twice as big.

This may not a huge issue, you may think... yet, rethinking is necessary. Imagine an array. Every pointer in an array is now twice as big. Every object pointer (and you know that there are quite a lot of objects in your JVM) now consumed twice as much memory as it did before.

I often suggested to my customers to rethink their 64bit strategy unless they are willing to add a lot more memory to their machine in order to get an actual benefit. This was often combined with GC tweaking. After all, the larger the heap, the more there is to clean up once GC occours (a gross over-generalization, I know).

There is a solution to our pains, though. This year Sun released a Performance Release of the JRE, which adds a the UseCompressedOops flag. Don't confuse the acronym OOP with object-oriented programming, in this very case it stands for ordinary object pointers. By starting your JVM with this flag, you tell it to behave like a 32bit/64bit-hybrid, as it will use 32bit object pointers and thus conserves a respectable amount of memory (generally about 30%) which your application can use and at the same time allows you to break free from the 32bit JVM heap size and register limitations mentioned previously.

Why don't you give it a try yourself? Simply start your application with the command line addition -XX:+UseCompressedOops and see what happens. I am quite sure you will see an improvement.

The only downside with all this is, that you will have to register to get the aforementioned Performance Release.

October 16, 2008

The new and improved Java SE

Great news! The long awaited Java SE 1.6u10 has finally been released.

Besides a long list of bug fixes, this new version also sets the stage for JavaFX by making Java modular. Users don't need to download the entire JRE, instead, only the modules needed for your Applet (i.e. a JavaFX RIA), will be downloaded. Should any of the Java applications executed on the user's machine need additional modules, they will be downloaded automatically.

Furthermore, Java desktop applications can now benefit of DirectX hardware accelerators out of the box and a new and modern Swing Look & Feel called Nimbus, has been added.

All in all, with the new version of Java SE, Sun's primary concern is to make the Java experience much more pleasent for end-users... and from what I can see so far, they seem to have done a good job.

October 7, 2008

Reliable monetary calculations

As you all probably know, reliable and correct monetary and scientific calculations in Java aren't as easy as it may seem. Many Java newbies and in some cases even intermediate Java developers, frequently use the data type double for monetary calculations. What's worse, for scientific applications there is no support worth mentoining, at all.

Now, if you build a small scale web page, you may never encounter rounding errors when dealing with this data type. However, if you are in the business of handling big amounts of cash, where fractions of a cent spread over millions of transactions could render losses in the tens or hundreds of thousands of dollars, you definitely should rethink your strategy.

Right now, what most people do, is using either BigDecimal or even calculating everything with 64 bit integers to avoid dealing with floating point arithmetic inaccuracies found in the primitive double data type.

There is nothing wrong in doing this, however, what about actually treating those essentially ambiguous floating point numbers as amounts of money. What about a data type called Money so you give those numbers a meaning. What if there was built in support in Java that treats money as a unit of measurement so you give those numbers a clear meaning?

A framework for this will likely find it's way into Java 7 and for those of you wanting to get a head-start is to download a fully functioning and mature reference implementation called JScience. I used it in one of my recent projects and I would like to share some very simple examples.

Converting from Euros to Swedish Crownes

import org.jscience.economics.money.Currency;
import org.jscience.physics.amount.Money;
import javax.measure.unit.Unit

public class ConvertCurrency {
 public static void convertSekToEur(double value) {
  Currency sek = new Currency("SEK");
  // Exchange rate SEK to SEK is 1.00
  sek.setExchangeRate(1.00);

  Currency eur = new Currency("EUR");
  // Exchange rate for EUR to SEK is 9.72
  eur.setExchangeRate(9.72);

  // Amount of money in SEK received
  Amount<Money> received = Amount.valueOf(value, sek);

  // Units should be printed with the Euro symbol
  UnitFormat.getInstance().label(Currency.EUR, "€");

  // Convert to SEK to EUR and get a localized text string
  String res = received.to(eur).toText();

  // Should print "value €", depending on Locale
  System.out.println("Teller returned: " + res);
 }
}


I know, this isn't all that impressive, but if you investigate the API further, you will notice, that very powerful things can be done with JScience.

Also, be aware that in the above example, I didn't set a reference currency. This means, that I had to set the exchange rate for both currencies. If I'd set SEK as the reference currency by using the Currency.setReferenceCurrency-method, the exchange rate for SEK would have been obsolete. Naturally, most apps will have a reference currency.

The distance in money

Imagine you were to put 50 Euro bank notes on the street all the way from Stockholm to Malmö. That's a distance of about 700 kilometers. How much money would you actually need?

import org.jscience.economics.money.Currency;
import org.jscience.economics.money.Money;
import org.jscience.physics.amount.Amount;

import javax.measure.quantity.Length;
import javax.measure.unit.SI;

public class DistanceInMoney {
 public static void main(String[] args) {
  // Distance between Stockholm and Malmö
  Amount<Length> distanceSthlmMmo = Amount.valueOf(700, SI.KILOMETER);

  // Length of a banknote
  Amount<Length> lengthBankNote = Amount.valueOf(15, SI.CENTIMETER);

  // Value of that banknote
  Amount<Money> bankNoteValue = Amount.valueOf(50, Currency.EUR);

  // Calculate how many banknotes are needed
  Amount<?> bankNotesNeeded = distanceSthlmMmo.to(SI.CENTIMETER).divide(lengthBankNote);

  // Show how much money you will need in total
  System.out.println("Money needed: " + bankNoteValue.times(bankNotesNeeded));
 }
}


Of course, this can also be done manually, but it's just to show that you give a meaning to numbers by using Amount<Length> or Amount<Money>. As in this number is an amount of money.

Calculating the cost for a trip

The last example is quite neat also. I admit, it's a simplified version of an example provided by the makers of JScience, however, I am not ashamed. I like it and that's why I post it :-)

So, how much does it cost to drive from Stockholm to Uppsala with my car...

import org.jscience.economics.money.Currency;
import org.jscience.economics.money.Money;
import org.jscience.physics.amount.Amount;

import javax.measure.quantity.Length;
import javax.measure.unit.NonSI;
import javax.measure.unit.SI;

public class TripCost {
 public static void main(String[] args) {
  // Our reference currency is SEK
  Currency.setReferenceCurrency(new Currency("SEK"));

  // My car drives 12,5km with one liter of petrol
  Amount<?> enginesThirst = Amount.valueOf(12.5,   SI.KILOMETER.divide(NonSI.LITER));

  // Fuel costs 12 SEK per liter
  Amount<?> fuelPrice = Amount.valueOf(12, Currency.getReferenceCurrency().divide(NonSI.LITER));

  // The distance to Uppsala is 50km
  Amount<Length> distanceToUppsala = Amount.valueOf(50, SI.KILOMETER);

  // Calculate the cost
  Amount<Money> cost = distanceToUppsala.divide(enginesThirst).times(fuelPrice).to(Currency.getReferenceCurrency());
  System.out.println("Trip costs: " + cost.toString());
 }
}


Again, this is no magic. You can do all this manually, however, isn't it quite helpful to actually treat units and amounts specifically as units, amounts and quantities?

Conclusion

So, what are the benefits besides the obvious? Well, JScience has a wealth of SI and NonSI units to do calculations, it has special numerical datatypes which guarantee IEEE754 accuracy and especially for scientific applications, this is a great treat to us all.

You probably remember the disaster with a NASA space probe a couple of years ago. Due to some mix-ups with units of measurement, millions went up in smoke. This sort of ambiguity should be a thing of the past with JScience (JSR-275).