tags:

views:

863

answers:

8
+7  Q: 

Java Object Reuse

Should Java Objects be reused as often as it can be reused ? Or should we reuse it only when they are "heavyweight", ie have OS resources associated with it ?

All old articles on the internet talk about object reuse and object pooling as much as possible, but I have read recent articles that say new Object() is highly optimized now ( 10 instructions ) and Object reuse is not as big a deal as it used to be.

What is the current best practice and how are you people doing it ?

+7  A: 

I let the garbage collector do that kind of deciding for me, the only time I've hit heap limit with freshly allocated objects was after running a buggy recursive algorithm for a couple of seconds which generated 3 * 27 * 27... new objects as fast as it could.

Do what's best for readability and encapsulation. Sometimes reusing objects may be useful, but generally you shouldn't worry about it.

Esko
+8  A: 

If you use them very intensively and the construction is costly, you should try to reuse them as much as you can.

If your objects are very small, and cheap to create ( like Object ) you should create new ones.

For instance connections database are pooled because the cost of creating a new one is higher than those of creating .. mmhh new Integer for instance.

So the answer to your question is, reuse when they are heavy AND are used often ( it is not worth to pool a 3 mb object that is only used twice )

Edit:

Additionally, this item from Effective Java:Favor Immutability is worth reading and may apply to your situation.

OscarRyz
+1 Another good snippet from Bloch (second ed.) is Item 5, "Avoid creating unnecessary objects". The last few paragraphs of this Item have some good bits of advice and information.
Rob Hruska
A: 

The rule of thumb should be to use your common sense and reuse objects when their creation consumes significant resources such as I/O, network traffic, DB connections, etc...

If it's just creating a new String(), forget about the reuse, you'll gain nothing from it. Code readability has higher preference.

Yuval A
+2  A: 

I would worry about performance issues if they arise. Do what makes sense first (would you do this with primatives), if you then run a profiling tool and find that it is new causing you problems, start to think about pre-allocation (ie. when your program isn't doing much work).

Re-using objects sounds like a disaster waiting to happen by the way:

SomeClass someObject = new SomeClass();

someObject.doSomething();
someObject.changeState();
someObject.changeOtherState();
someObject.sendSignal();
// stuff

//re-use 
someObject.reset(); // urgh, had to put this in to support reuse
someObject.doSomethingElse(); // oh oh, this is wrong after calling changeOtherState, regardless of reset
someObject.changeState(); // crap, now this is wrong but it's not obvious yet
someObject.doImportantStuff(); // what's going on?
billybob
Of course. If you re-use, you have to design for object reuse, and not let it to luck. Database connections are reused, and they have a "close" method to clean up the resources ( originally they also drop the connection ) but DatabasePools wrap those connections to let the cleanup happen but lea..
OscarRyz
..leave the connection open. Of course it would be a disasters for instance to re-insert a previously inserted object. Or commit a previously started transaction used somewhere else in the code. You should consider and design for reuse very seldom.
OscarRyz
Sure but these are things that loan themselves to re-use. The op was talking about large objects (whose state would presumably be complex) rather than actual resources.
billybob
I agree with you.
OscarRyz
A: 

Object creation is certainly faster than it used to be. The newer generational GC in JDKs 5 and higher are improvements, too.

I don't think either of these makes excessive creation of objects cost-free, but they do reduce the importance of object pooling. I think pooling makes sense for database connections, but I don't attempt it for my own domain objects.

Reuse puts a premium on thread-safety. You need to think carefully to ensure that you can reuse objects safely.

If I decided that object reuse was important I'd do it with products like Terracotta, Tangersol, GridGain, etc. and make sure that my server had scads of memory available to it.

duffymo
+4  A: 

Let the garbage collector do its job, it can be considered better than your code.

Unless a profiler proves it guilty. And don't even use common sense to try to figure out when it's wrong. In unusual cases even cheap objects like byte arrays are better pooled.

  • Rule 1 of optimization: don't do it.
  • Rule 2 (for experts only): don't do it yet.
Darron
A: 

Second the above comments.

Don't try and second guess the GC and Hotspot. Object pooling may have been useful once but these days its not so useful unless you are talking about database connections or unique system resources.

Just try and write clean and simple code and be amazed at what Hotspot can do.

Why not use VisualVM or a profiler to take a look at your code?

Fortyrunner
+1  A: 

Object creation is cheap, yes, but sometimes not cheap enough.

If you create a lot (and I mean A LOT) temporary objects in rapid succession, the costs for the garbage collector are considerable. However even with a good profiler you may not necessarily see the costs easily, as the garbage collector nowadays works in short intervals instead of blocking the whole application for a second or two.

Most of the performance improvements I got in my projects came from either avoiding object creation or avoiding the whole work (including the object creation) through aggressive caching. No matter how big or small the object is, it still takes time to create it and to manage the references and heap structures for it. (And of course, the cleanup and the internal heap-defrag/copying also takes time.)

I would not start to be religious about avoiding object creation at all cost, but if you see a jigsaw pattern in your memory-profiler, it means your garbage collector is on heavy duty. And if your garbage collector uses the CPU, the CPI is not available for your application.

Regarding object pooling: Doing it right and not running into either memory leaks or invalid states or spending more time on the management than you would save is difficult. So I never used that strategy.

My strategy has been to simply strive for immutable objects. Immutable things can be cached easily and therefore help to keep the system simple.

However, no matter what you do: Make sure you check your hotspots with a profiler first. Premature optimization is the root of most evilness.

Thomas Morgner