Software Development – Java – Open Source

Book Review: Wicket In Action

Monday, August 25th, 2008 at 11:31 pm

Alright here is the short summary: Martijn and Eelco have done an amazing job writing a comprehensive yet easy to read book, that covers pretty much every aspect of Wicket and is more than recommended for everyone who wants to get started with Wicket.

Starting with the introduction they give you a good idea what Wicket is and how it came into life. It outlines a lot of the reasons why Model 2 web frameworks suck and how Wicket does a better job. This already got me hooked because it’s always nice to read about different approaches.

Wicket Architecture

After explaining the wicket architecture they introduce the first sample application which is … no, not another pet store … a cheese store ;) But as you continue reading you will find that their writing is not cheesy at all. They’ve got a fresh style of writing which is not too boring but still delivers all the technical details you need, to thoroughly understand what’s going on.

The first two chapters of part 2 of the book go into detail about Wicket’s core elements: Models and Components. Understanding those and how they interact is the cornerstone of understanding Wicket.
But to really fill your models and components with life, you will need to interact with your user and fill your application with data. Explaining how to process user input using forms including validation and what different layout concepts Wicket has to offer is covered by the next two chapters.

Advanced Topics

So what’s next? I already gained the knowledge to write my basic Wicket application, but there are still some advanced topics to cover:

  • Developing reusable components
  • Images, CSS and scripts: working with resources
  • Rich components and AJAX

If you ever build a bigger web application you’ll realize quickly that there are some topics left to explain. Does Wicket provide means of authentication and authorization? How does i18n work? Oh, and I want my application to integrate with Spring and Hibernate! And how do I test my wicked Wicket application?
Fortunately all those questions and more are answered in the last part of the book called “Preparing for the real world”.

Awesome Book

Martijn and Eelco do a great job getting you up to speed with Wicket. But it’s not only about getting through those sample applications. What I love about the book is that it actually provides hands on instructions for real world applications which is often missing from such books. It’s probably due to the fact that they are both members of the core Wicket team and use Wicket on a daily basis. They are not another example of those authors that just decide that they are going to write a book about a topic, and then do the tutorials and hang around on the mailing lists to gather just enough information to fill a book.

To summarize: Well done! I wish this book was available about a year ago, when one of my colleagues tried to build his first Wicket application!

If you are thinking of buying the book, you should buy it now as they offer a 35% discount until the end of August.

Back In Business

Monday, August 25th, 2008 at 11:10 pm

I didn’t write anything for ages. The reason is I was travelling Australia from February to June. And in July I started working at Atlassian in Sydney. So I have been pretty busy down here getting settled at the new job and buying furniture and all that stuff to feel a little bit more at home, when I come back to our little 12sqm room ;)

I hope to write a little more often, now that everything is back to normal and having all those smart guys at Atlassian to inspire me!

Performance Tuning: Object Creation Overhead

Saturday, December 1st, 2007 at 7:53 pm

While working on a Jackrabbit issue I came across a method that is called about a million times for certain requests. In this method an ArrayList instance and a few Integer instances were created on each call to eventually build up a list of ints. I thought I might give it a try and use an int array instead – lo and behold! That gave me an overall performance gain of about 40%.

I wrote this little test code to show the difference:

import java.util.ArrayList;
import java.util.List;


public class ArrayPerformance {

    private static final int LOOP_COUNT = 10000000;
    private static final int ARRAY_SIZE = 10;

    private static void buildArrayList() {
        long start = System.currentTimeMillis();
        for (int i = 0; i < LOOP_COUNT; i++) {
            List values = new ArrayList(ARRAY_SIZE);
            for (int j = 0; j < ARRAY_SIZE; j++) {
                values.add(Integer.valueOf(j));
            }
        }
        long end = System.currentTimeMillis();
        printTime(start, end, "ArrayList");
    }
   
    private static void buildArray() {
        long start = System.currentTimeMillis();
        for (int i = 0; i < LOOP_COUNT; i++) {
            int[] values = new int[ARRAY_SIZE];
            for (int j = 0; j < ARRAY_SIZE; j++) {
                values[j] = j;
            }
        }
        long end = System.currentTimeMillis();
        printTime(start, end, "array");
    }

    private static void printTime(long start, long end, String label) {
        System.out.printf("%-10s: %5dms\n", new Object[]{label, Long.valueOf(end-start)});
    }
   
    public static void main(String[] args) {
        for (int i = 0; i < 5; i++) {
            buildArray();
            buildArrayList();
        }
    }
   
}

The resulting output was this:

array     :   475ms
ArrayList :  1200ms
array     :   353ms
ArrayList :  1158ms
array     :   337ms
ArrayList :   921ms
array     :   341ms
ArrayList :   921ms
array     :   341ms
ArrayList :   918ms

Which shows that after some warming up the variant using an ArrayList with Integers to build up a list of ints is roughly about 3 times slower than using a plain int array.

What do I learn from this?

If you know about code sections in your code base which are called millions of times make sure you try to find a solution without creating short living object instances, because even if the current JVM is quite fast creating and collection object instances, it still eats some CPU.
This might lead to solutions that are not object oriented anymore, but this is a small drawback if it gives a performance critical part of your application a speedup.

Another thing is that using natives like ints or longs is always preferable over Integer or Long objects for performance critical code. Lucene for example uses natives a lot to get the best performing code.

Suns Troubleshooting Guide for Java

Monday, September 17th, 2007 at 12:31 pm

Suns Troubleshooting Guide for Java provides a nice overview of available tools to analyze and monitor Java processes. I would guess that a lot of Java developers doesn’t know them.

I recently had to identify a performance problem on one of our production servers. The application appeared to hang every few seconds and then continue normal operation. Using jstat I quickly discovered that there were a lot of objects created just to be garbage collected right after. This was the output of jstat:

S0     S1     E      O      P     YGC     YGCT    FGC    FGCT     GCT    LGCC                 GCC
0,00   0,00 100,00 100,00  89,75  10546  726,162  1192 12922,944 13649,106 Allocation Failure   unknown GCCause
0,00   0,00 100,00 100,00  89,44  10546  726,162  1192 12922,944 13649,106 Allocation Failure   unknown GCCause
0,00   0,00  21,93 100,00  89,47  10546  726,162  1192 12934,808 13660,970 unknown GCCause      No GC
0,00   0,00  32,41 100,00  89,48  10546  726,162  1192 12934,808 13660,970 unknown GCCause      No GC
0,00   0,00  42,44 100,00  89,48  10546  726,162  1192 12934,808 13660,970 unknown GCCause      No GC
S0     S1     E      O      P     YGC     YGCT    FGC    FGCT     GCT    LGCC                 GCC
0,00   0,00  56,79 100,00  89,48  10546  726,162  1192 12934,808 13660,970 unknown GCCause      No GC
0,00   0,00  68,61 100,00  89,48  10546  726,162  1192 12934,808 13660,970 unknown GCCause      No GC
0,00   0,00  78,02 100,00  89,48  10546  726,162  1192 12934,808 13660,970 unknown GCCause      No GC
0,00   0,00  88,74 100,00  89,48  10546  726,162  1192 12934,808 13660,970 unknown GCCause      No GC
0,00   0,00 100,00 100,00  89,48  10546  726,162  1193 12934,808 13660,970 Allocation Failure   unknown GCCause
S0     S1     E      O      P     YGC     YGCT    FGC    FGCT     GCT    LGCC                 GCC
0,00   0,00 100,00 100,00  89,48  10546  726,162  1193 12934,808 13660,970 Allocation Failure   unknown GCCause
0,00   0,00 100,00 100,00  89,48  10546  726,162  1193 12934,808 13660,970 Allocation Failure   unknown GCCause
0,00   0,00 100,00 100,00  89,48  10546  726,162  1193 12934,808 13660,970 Allocation Failure   unknown GCCause
0,00   0,00 100,00 100,00  89,48  10546  726,162  1193 12934,808 13660,970 Allocation Failure   unknown GCCause
0,00   0,00 100,00 100,00  89,48  10546  726,162  1193 12934,808 13660,970 Allocation Failure   unknown GCCause
S0     S1     E      O      P     YGC     YGCT    FGC    FGCT     GCT    LGCC                 GCC
0,00   0,00 100,00 100,00  89,48  10546  726,162  1193 12934,808 13660,970 Allocation Failure   unknown GCCause
0,00   0,00 100,00 100,00  89,48  10546  726,162  1193 12934,808 13660,970 Allocation Failure   unknown GCCause
0,00   0,00 100,00 100,00  89,48  10546  726,162  1193 12934,808 13660,970 Allocation Failure   unknown GCCause
0,00   0,00 100,00 100,00  89,48  10546  726,162  1193 12934,808 13660,970 Allocation Failure   unknown GCCause
0,00   0,00 100,00 100,00  89,48  10546  726,162  1193 12934,808 13660,970 Allocation Failure   unknown GCCause
S0     S1     E      O      P     YGC     YGCT    FGC    FGCT     GCT    LGCC                 GCC
0,00   0,00 100,00 100,00  89,48  10546  726,162  1193 12934,808 13660,970 Allocation Failure   unknown GCCause
0,00   0,00  24,36 100,00  89,51  10546  726,162  1193 12946,347 13672,509 unknown GCCause      No GC

The “E” column denotes percent of Eden space used. In the time where this value is 100% the application doesn’t respond until the garbage collection took place.

Using jstack I was able to find out what the server was doing while inflating the heap.

All this was done on a server running in production without using any additional profilers!

Another nice feature is the -XX:+HeapDumpOnOutOfMemoryError option mentioned in section 3.3.3.4 of the guide. I always set this option for production servers. This way you always have a memory dump available to analyze, even if the support team only restarted the application without taking a heap dump.

Or take jmap for example. You can not only get some heap statistics but also generate a heap dump while the application is running.

So make sure you know about the tools available as they might become useful if your application ever gets into trouble ;)