aspose file tools*
The moose likes Java in General and the fly likes Avoiding memory allocation? Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Spring in Action this week in the Spring forum!
JavaRanch » Java Forums » Java » Java in General
Bookmark "Avoiding memory allocation?" Watch "Avoiding memory allocation?" New topic
Author

Avoiding memory allocation?

Dan Bizman
Ranch Hand

Joined: Feb 25, 2003
Posts: 387
I've read in a number of places the recommendation that you should avoid memory allocation (in Java) wherever possible. How is this done? I thought Java was a memory-managed language where you didn't have control over that. Are there ways to avoid memory allocation? What are they? Are they worth it?
Peter Chase
Ranch Hand

Joined: Oct 30, 2001
Posts: 1970
Most places that recommend avoiding allocation are very old and/or just plain wrong. Modern JVMs are very fast at allocation and deallocation. They have special generational garbage-collectors to help with this.

However, Java objects are always initialised after allocation. Even if there is no programmer-generated code to assign initial values, the JVM is required to assign agreed values to fields etc. Therefore, initialisation of objects with a lot of fields could take significant time. Arrays are also always initialised, so very large arrays can take a lot of time to initialise.

Some objects lend themselves to re-use. If this is the case, then by all means re-use objects and save on allocation/initialisation/deallocation costs. But do not compromise the understandability of your code to enable re-use.

In my code, I do occasionally do things explicitly to enable re-use. But this is only done when profiling has shown these to be benficial. In particular, I have a "recycler" for big byte arrays, because I use a lot of big byte arrays and initialising lots of new ones was getting expensive.


Betty Rubble? Well, I would go with Betty... but I'd be thinking of Wilma.
Ernest Friedman-Hill
author and iconoclast
Marshal

Joined: Jul 08, 2003
Posts: 24187
    
  34

Don't avoid allocation; avoid excessive and unnecessary allocation.

The classic example is something like this:



Each time through the loop, this allocates several StringBuffer objects, which each contain an array, and several Strings, which each contain an array -- something like 80,000 objects altogether. That's a lot of work for the JVM, especially since code that does the same thing while allocating only four objects (one StringBuffer, one String, and their member arrays) is no more complex:



(If you don't believe me about buffer.append(i) not allocating any objects, go look at the source code -- it's very highly optimized.)


[Jess in Action][AskingGoodQuestions]
Dan Bizman
Ranch Hand

Joined: Feb 25, 2003
Posts: 387
Originally posted by Ernest Friedman-Hill:
Don't avoid allocation; avoid excessive and unnecessary allocation.

The classic example is something like this:



Each time through the loop, this allocates several StringBuffer objects, which each contain an array, and several Strings, which each contain an array -- something like 80,000 objects altogether. That's a lot of work for the JVM, especially since code that does the same thing while allocating only four objects (one StringBuffer, one String, and their member arrays) is no more complex:



(If you don't believe me about buffer.append(i) not allocating any objects, go look at the source code -- it's very highly optimized.)


Thanks for the reply.

The only examples I've seen are of String usage. Are there others to be mindful of?

I do try to reuse objects where possible, and if I can null out the references when they're no longer needed. But I'm guessing that's a small to zero gain.
Ernest Friedman-Hill
author and iconoclast
Marshal

Joined: Jul 08, 2003
Posts: 24187
    
  34

The fact that Strings are a handy example for this kind of discussion have led some people to believe that Strings are evil. That's not true at all; it's just that an example like this is easy for people to understand and this kind of thing comes up so often in real code. I think the crucial reason for this is that the allocation is hidden -- you don't call "new", so you don't think about it. Neither the right way nor the wrong way involves calling "new".

A similar kind of thing that does involve calling new would be accumulating primitives in an array. Let's say you're writing a class like ArrayList which holds an int[] internally. There's an add() method which adds an item to the array.

There are two ways to write a class like this: a wrong way which allocates lots of unnecessary objects, and a right way which doesn't. The wrong way is to have the array always be the exact right size. Whenever add() is called, you create an array one element longer, copy the old data, insert the new int, discard the old array. Every add() causes an allocation and data copy. When the array gets big, this can get expensive! I've seen lots of newbie code like this.

The other strategy is to keep a separate count of the valid elements in the array, and let the array be bigger-than-needed most of the time. Then you only have to allocate-and-copy occasionally, at the expense of a little wasted space. It's generally a good trade!
Ilja Preuss
author
Sheriff

Joined: Jul 11, 2001
Posts: 14112
Originally posted by Dan Bizman:
I do try to reuse objects where possible


Be aware that very short lived objects are actually better for the GC than objects with a medium live time. So, if you reuse objects blindly, you could in fact make things worse.


null out the references when they're no longer needed


You know that you don't need to do that when the reference gets out of scope anyway?

But I'm guessing that's a small to zero gain.


Yes, if at all. It really only makes sense in *very* specific cases. Typically it will do more harm than good, if "only" by making the code more complex than necessary.


The soul is dyed the color of its thoughts. Think only on those things that are in line with your principles and can bear the light of day. The content of your character is your choice. Day by day, what you do is who you become. Your integrity is your destiny - it is the light that guides your way. - Heraclitus
Ken Blair
Ranch Hand

Joined: Jul 15, 2003
Posts: 1078
Originally posted by Ilja Preuss:
You know that you don't need to do that when the reference gets out of scope anyway?


Which is why you should be mindful of exposing references and variables in general to excessive scope.
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
Well, it's one reason, not the only one.


"I'm not back." - Bill Harding, Twister
 
It is sorta covered in the JavaRanch Style Guide.
 
subject: Avoiding memory allocation?