+6  A: 

This is similar to the flyweight pattern detailed in the GoF patterns book (see edit below). Object pools have gone out of favour in a "normal" virtual machine due to the advances made in reducing the object creation, synchronization and GC overhead. However, these have certainly been around for a long time and it's certainly fine to try them to see if they help!

Certainly Object Pools are still in use for objects which have a very expensive creation overhead when compared with the pooling overheads mentioned above (database connections being one obvious example).

Only a test will tell you whether the pooling approach works for you on your target platforms!

EDIT - I took the OP "re-used wherever possible" to mean that the objects were immutable. Of course this might not be the case and the flyweight pattern is really about immutable objects being shared (Enums being one example of a flyweight). A mutable (read: unshareable) object is not a candidate for the flyweight pattern but is (of course) for an object pool.

oxbow_lakes
which doesn't answer the question: Should the OP do it
jalf
I thought it was kind of implicit in the answer. If the GoF wrote a book which included this as a common pattern then it follows that it is a potential solution to the problem
oxbow_lakes
A: 

You're talking about a pool of reusable object instances.

class MyObjectPool { 
    List<MyObject> free= new LinkedList<MyObject>();
    List<MyObject> inuse= new LinkedList<MyObject>();
    public MyObjectPool(int poolsize) {
        for( int i= 0; i != poolsize; ++i ) {
           MyObject obj= new MyObject();
           free.add( obj );
        }
    }
    pubic makeNewObject( ) {
        if( free.size() == 0 ) {
            MyObject obj= new MyObject();
            free.add( obj );
        }
        MyObject next= free.remove(0);
        inuse.add( next );
        return next;
   }
   public freeObject( MyObject obj ) {
       inuse.remove( obj );
       free.add( obj );
   }
}
        return in
S.Lott
+2  A: 

Normally, I'd say this was a job for tuning the GC parameters of the VM, the reduce the spiky-ness, but for mobile apps that isn't really an option. So if the JVms you are using cannot have their GC behavioure modified, then old-fashioned object pooling may be the best solution.

The Apache Commons Pool library is good for that, although if this is a mobile app, then you may not want the library dependency overhead.

skaffman
A: 

Given that this answer suggests that there is not much scope for tweaking garbage collection itself in J2ME then if GC is an issue the only other option is to look at how you can change your application to improve performance/memory usage. Maybe some of the suggestions in the answer referenced would apply to your application.

As oxbow_lakes says, what you suggest is a standard design pattern. However, as with any optimisation the only way to really know how much it will improve your particular application is by implementing and profiling.

Mark
+1  A: 

You could check out this link describing enhancements to the Concurrent Mark Sweep collector, although I'm not sure it's available for J2ME. In particular note:

"The concurrent mark sweep collector, also known as the concurrent collector or CMS, is targeted at applications that are sensitive to garbage collection pauses."

... "In JDK 6, the CMS collector can optionally perform these collections concurrently, to avoid a lengthy pause in response to a System.gc() or Runtime.getRuntime().gc() call. To enable this feature, add the option"

-XX:+ExplicitGCInvokesConcurrent
Adamski
+2  A: 

Actually, that graph looks pretty healthy to me. The GC is reclaiming lots of objects and the memory is then returning to the same base level. Empirically, this means that the GC is working efficiently.

The problem with object pooling is that it makes your app slower, more complicated and potentially more buggy. What is more, it can actually make each GC run take longer. (All of the "idle" objects in the pool are non-garbage and need to be marked, etc by the GC.)

Stephen C
+1  A: 

Does J2ME have a generational garbage collector? If so it does many small, fast, collections and thus the pauses are reduced. You could try reducing the eden memory space (the small memory space) to increase the frequency and reduce the latency for collections and thus reduce the pauses.

Although, come to think of it, my guess is that you can't adjust gc behaviour because everything probably runs in the same VM (just a guess here).

Michael Wiles
+1  A: 

Check out this link. In particular:

Just to list a few of the problems object pools create: first, an unused object takes up memory space for no reason; the GC must process the unused objects as well, detaining it on useless objects for no reason; and in order to fetch an object from the object pool a synchronization is usually required which is much slower than the asynchronous allocation available natively.

Aviad Ben Dov