Newsletter sign-up
View all newsletters

Enterprise Java Newsletter
Stay up to date on the latest tutorials and Java community news posted on JavaWorld

Sponsored Links

Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs

Java performance programming, Part 1: Smart object-management saves the day

Learn how to reduce program overhead and improve performance by controlling object creation and garbage collection

  • Print
  • Feedback

Page 4 of 6

Owned objects

By using some one-time allocations, we can create a set of objects required for formatting, then reuse these dedicated objects as needed. This set of objects is then owned by the code which uses them. For example, if we apply this approach using instance variables, so that each instance of the containing class owns a unique copy of the objects, we'd have something like this:

    ...
    // Allocate dedicated time formatting objects as member variables.
    private final Date convertDate = new Date();
    private final DateFormat convertFormat = DateFormat.getDateInstance();
    private final StringBuffer convertBuffer = new StringBuffer();
    private final FieldPosition convertField = new FieldPosition(0);
    ...
        // Get the default string for time.
        long time = ...;
        convertDate.setTime(time);
        convertBuffer.setLength(0);
        StringBuffer output =
            dateFormatter.format(convertDate, convertBuffer, convertField);
        String display = output.toString();
        ...


This code is considerably longer than the original statement, but executes much more quickly because the only object constructed each time through is the output string. In a test run with 100,000 iterations, this code took only 8 seconds to execute, as opposed to 50 seconds for the original technique. This approach does incur some additional memory usage as the price of the speed advantage, since the objects used for the formatting are kept permanently allocated instead of being freed when not in use. But if the code is executed frequently, it's a very good trade-off.

It's worth pointing out that the same technique applies if you have an inner loop within a method doing a large number of iterations. You may not need to have a set of the objects used within the loop permanently owned by the object containing the method, but you can still move the object allocations outside the loop so that they're only done once. In this case, our example code might look like this:

        // Allocate objects to be used inside loop.
        Date date = new Date();
        DateFormat formatter = DateFormat.getDateInstance();
        StringBuffer buffer= new StringBuffer();
        FieldPosition field = new FieldPosition(0);
        // Execute the loop.
        for (...) {
            // Get the default string for time.
            long time = ...;
            date.setTime(time);
            buffer.setLength(0);
            StringBuffer output = formatter.format(date, buffer, field);
            String display = output.toString();
        }


This dedicated object reuse technique often works especially well in combination with the approach of using primitive values in place of objects, as described above. A dedicated object can be initialized from the primitive values and passed to class library methods that expect an object of the original type. The use of the dedicated Date object above provides an example of this.

Multithreading owned objects

If we have a set of owned objects, and multiple threads can execute the code that uses the objects concurrently, we need to prevent conflicts between the different threads' usage of the objects. The easiest way to accomplish this is to designate one of the objects as the lock for the whole set, and enclose the code using the set of objects within a synchronized block on the lock object. This adds the overhead of a locking operation for each use of the owned objects, but the locking overhead is low in comparison to the object creation time.

  • Print
  • Feedback

Resources
  • Benchmarks
  • Recent JavaWorld articles covering object pools for resource management