Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I was told by a colleague that in Java object creation is the most expensive operation you could perform. So I can only conclude to create as few objects as possible.

This seems somewhat to defeat the purpose of object oriented programming. If we aren't creating objects then we are just writing one long class C style, for optimization?

share|improve this question
12  
"Java object creation is the most expensive operation you could perform". Mind sharing the source of that claim? –  Songo May 22 '12 at 9:23
46  
And - most expensive operation as compared to what? Compared to calculating pi to 900 digits or compared to incrementing an int? –  jasonk May 22 '12 at 9:55
    
Might they have been talking about a particular part of that specific object creation? I'm thinking how Apple uses a queue for tableViewCells. Perhaps your colleague was suggesting to create a few objects and reuse them due to some overhead associated with those specific objects? Just trying to figure out why they'd make such a claim. –  Tyler DeWitt May 22 '12 at 17:21
    
Most expensive (primitive) operation is actually creating a very large array... –  Mehrdad May 23 '12 at 6:20
    
This is one of the most funny things I've ever heard about programming .) –  Mert May 24 '12 at 8:58
show 1 more comment

We're looking for long answers that provide some explanation and context. Don't just give a one-line answer; explain why your answer is right, ideally with citations. Answers that don't include explanations may be removed.

11 Answers

up vote 212 down vote accepted
+50

Your colleague has no idea what they are talking about. Your most expensive operation would be listening to them, they wasted your time mis-directing you to information at least a decade out of date as well as you having to spend time posting here and researching the Internet for the truth.

Hopefully they are just ignorantly regurgitating something they heard or read from a decade ago and don't know any better. I would take anything else they say as suspect as well, this should be a well known fallacy by anyone that keeps up to date either way.

Everything other than primitives ( int, long, double, etc ) are Objects in Java. There is no way to avoid Object creation in Java.

Object creation in Java due to its memory allocation strategies is faster than C++ in most cases and for all practical purposes compared to everything else in the JVM can be considered "free".

Early as in late 1990's early 2000s JVM implementations did have some performance overhead in the actual allocation of Objects. This hasn't been the case since at least 2005.

If you tune -Xmx to support all the memory you need for your application to run correctly, the GC may never have to run and sweep most of the garbage in the modern GC implementations, short lived programs may never GC at all.

It doesn't try and maximize free space, which is a red herring anyway, it maximizes performance of the runtime. If that means the JVM Heap is almost 100% allocated all the time, so be it. Free JVM heap memory doesn't give you anything just sitting there anyway.

There is a misconception that the GC will free memory back to the rest of the system in a useful way, this is completely false!

The JVM heap doesn't grow and shrink so that the rest of the system is positively affected by free memory in the JVM Heap. -Xmx allocates ALL of what is specified at startup and its heuristic is to never really release any of that memory back to the OS to be shared with any other OS processes until that instance of the JVM quits completely. -Xmx=1GB allocates 1GB of RAM regardless of how many objects are actually created at any given time. There are some settings that allow for percentages of the heap memory to be release, but for all practical purposes the JVM never is able to release enough of this memory for this to ever happen so no other processes can reclaim this memory, so the rest of the system doesn't benefit from the JVM Heap being free either. An RFE for this was "accepted" 29-NOV-2006, but nothing has ever been done about it. This is behavior is not considered a concern by anyone of authority.

There is a misconception that creating many small short lived objects causes the JVM to pause for long periods of time, this is now false as well

Current GC algorithms are actually optimized for creating many many small objects that are short lived, that is basically the 99% heuristic for Java objects in every program. Object Pooling will actually make the JVM preform worse in most cases. The only Objects that need pooling today are Objects that refer to finite resources that are external to the JVM; Sockets, Files, Database Connections, etc.

The modern GC algorithms don't have this problem because they don't deallocate on a schedule, they deallocate when free memory is needed in a certain generation. If the heap is big enough, then no deallocations happen long enough to cause any pauses.

Object Oriented Dynamic languages are beating C even now days on compute sensitive tests.

share|improve this answer
142  
+1: "Your most expensive operation would be listening to them ...". Best I've heard for some time. –  Cwan May 22 '12 at 8:16
18  
@DeadMG, even with the cumulative GC overhead, Java can be faster than C++ (e.g., due to the heap compaction, minimising cache misses for certain data structures). –  SK-logic May 22 '12 at 8:43
5  
@SK-logic: As the GC is non-deterministic, it's extremely difficult at best to actually prove that. As for minimising cache misses, it's hard to do that when every object must be another indirection, wasting cache space and increasing execution time. However, I contend that by simply using an appropriate allocator in C++ like object pool or memory arena, you can easily match or beat the performance of the garbage collector. For example, you can write a memory arena class that will perform faster than _alloca, amortized. –  DeadMG May 22 '12 at 8:49
9  
@DeadMG, what are you talking about? There are no extra indirections. And no, you cannot match the proper GC performance with the custom allocators, pools and all that. Please do not come back to this topic unless you're able to prove that you can infer a region-based memory management scheme for any possible program in, say, simple lambda calculus. You cannot compactify manually a custom binary tree coming from runtime-dependant data. –  SK-logic May 22 '12 at 8:52
6  
@Matsemann that is exactly the false information that the OP is referring to. It hasn't been accurate for a decade. Object polling is relevant for resources external to the JVM and that are finite, like DB Connections/Network Sockets. All that old mumbo jumbo about Object pooling in any other context is voodoo now. –  Jarrod Roberson May 22 '12 at 18:06
show 13 more comments

Actually, due to the memory management strategies that the Java language (or any other managed language) makes possible, object creation is little more than incrementing a pointer in a block of memory called the young generation. It's much faster than C, where a search for free memory has to be done.

The other part of the cost is object destruction, but it's hard to compare to C. The cost of a collection is based on the amount of objects saved long-term but the frequency of collections is based on amount of objects created... in the end, it's still much faster than C-style memory management.

share|improve this answer
5  
+1 Even though the garbage collector "just works", every Java programmer should learn about the generational garbage collector. –  benzado May 22 '12 at 13:16
10  
The newer versions of Java can do escape analysis, which means that it can allocate memory for objects that don't escape a method on the stack, so that cleaning them up is free - the garbage collector doesn't have to deal with those objects, they're automatically discarded when the method's stack frame is unwound (when the method returns). –  Jesper May 22 '12 at 14:28
3  
An the next step for escape analysis is to "allocate" memory for small object purely in registers (for example a Point object could fit in 2 general purpose registers). –  Joachim Sauer May 23 '12 at 5:34
3  
@Joachim Sauer: That's kind of what is done in the newer implementations of the HotSpot VM. It's called scalar replacement. –  someguy May 24 '12 at 15:02
1  
@someguy: I've read about it some time ago as the next thing, but didn't follow up to check if it's already done. It's excellent news to hear that we already have this. –  Joachim Sauer May 24 '12 at 19:31
show 1 more comment

Bottom line: Don't compromise your design in order to take shortcuts creating objects. Do avoid creating objects unnecessarily. If sensible, design to avoid redundant operations (of any sort).

Contrary to most answers - yes, object allocation DOES have a cost associated. It is a low cost, but you should avoid creating unnecessary objects. Same as you should avoid unnecessary anything in your code. Large object graphs make GC slower, imply longer execution times in that you are probably going to have more method calls, trigger more CPU cache misses, and increase likelihood of your process being swapped to disk in low RAM cases.

Before anyone rants about this being an edge case - I have profiled applications that, before optimising, created 20+MB of objects in order to process ~50 rows of data. This is fine in testing, until you scale up to a hundred requests a minute and suddenly you are creating 2GB of data per minute. If you want to do 20 reqs/sec you are creating 400MB of objects and then throwing it away. 20 reqs/sec is tiny for a decent server.

share|improve this answer
4  
I may add an example: In some cases it really makes no difference in terms of clarity of code but can make a more or less big difference in performance: When reading from streams, for instance, it is not uncommon to use something like while(something) { byte[] buffer = new byte[10240]; ... readIntoBuffer(buffer); ... which may be wasteful compared to e.g. byte[] buffer = new byte[10240]; while(something) { ... readIntoBuffer(buffer); .... –  Hanno Binder May 22 '12 at 9:41
    
+1: Unnecessary object creation (or rather cleaning up after removal) can definitely sometimes be costly. 3D Graphics/OpenGL code in java is one place where I have seen optimizations done to minimize the number of objects created since GC can otherwise wreak havoc with your framerate. –  Leo May 22 '12 at 14:10
    
Wow! 20+ MB to process 50 rows of data? Sounds crazy. In any case, are those objects long-lived? Because that's the case that would matter for GC. If on the other hand you're merely discussing memory requirements, that's unrelated to garbage collection or object creation efficiency... –  Andres F. May 22 '12 at 23:52
    
Objects are short-lived (less than 0.5sec in the general case). That volume of garbage still affects performance. –  jasonk May 23 '12 at 23:17
add comment

Other posters have rightly pointed out that object creation is extremely fast in Java, and that you should not usually worry about it in any normal Java application.

There are a couple of very special situations where is is a good idea to avoid object creation.

  • When you are writing a latency-sensitive application and wish to avoid GC pauses. The more objects you produce, the more GC happens and the greater the chance of pauses. This might be a valid consideration for relevant for games, some media applications, robotic control, high-frequency trading etc. The solution is to pre-allocate all the objects / arrays you need up front and re-use them. There are libraries that specialise in providing this kind of capability, e.g Javolution. But arguably, if you really care about low latency you should be using C/C++/assembler rather than Java or C# :-)
  • Avoiding boxed primitives (Double, Integer etc.) can be a very beneficial micro-optimisation in certain circumstances. Since unboxed primitives (double, int etc.) avoid the per-object overhead, they are much faster CPU intensive work like numerical processing etc. Typically, primitive arrays perform very well in Java so you want to use these for your number crunching rather than any other kinds of objects.
  • In constrained memory situations you want to minimise the number of (active) objects created since each objects carries a small overhead (typically 8-16 bytes depending on JVM implementation). In such circumstances you should prefer a small number of large objects or arrays to store your data rather than a large number of small objects.
share|improve this answer
    
Its worth noting that escape analysis will allow short lived (bounded life) objects to be stored on the stack, these objects can be deallocated for free ibm.com/developerworks/java/library/j-jtp09275/index.html –  Richard Tingle Jun 27 '13 at 10:36
    
@Richard: great point - escape analysis provides some very good optimisations. You have to be careful about relying on it though: it isn't guaranteed to happen in all Java implementations and in all circumstances. So you often need to benchmark to be sure. –  mikera Jun 27 '13 at 11:43
add comment

There is a kernel of truth in what your colleague is saying. I respectfully suggest the issue with object creation is actually garbage collection. In C++ the programmer can control precisely how memory is deallocated. The program can accumulate crud for as long or as short as it likes. Further, the C++ program can discard the crud using a different thread than the one that created it. Thus the thread currently working never has to stop to clean up.

In contrast, the Java Virtual Machine (JVM) periodically stops your code to reclaim unused memory. Most Java developers never notice this pause, since it is usually infrequent and very short. The more crud you accumulate or the more constrained your JVM is, the more frequent these pauses are. You can use tools like VisualVM to visualize this process.

In recent versions of Java, the garbage collection (GC) algorithm can be tuned. As a general rule, the shorter you want to make the pauses, the more expensive the overhead in the virtual machine (i.e. CPU and memory spent coordinating the GC process).

When might this matter? Any time you care about consistent sub-millisecond response rates, you'll care about GC. Automated trading systems written in Java tune the JVM heavily to minimize pauses. Firms that would otherwise write Java turn to C++ in situations where systems have to be highly responsive all the time.

For the record, I do not condone object avoidance in general! Default to object-oriented programming. Adjust this approach only if the GC gets in your way, and then only after trying to tune the JVM to pause for less time. A good book on Java performance tuning is Java Performance by Charlie Hunt and Binu John.

share|improve this answer
6  
Most modern JVM's support better garbage collection algorithms than "stop the world". The amortized time spent in garbage collection is frequently less than what is spent explicitly calling malloc/free. Also does C++ memory management run in a separate thread? –  user1249 May 22 '12 at 6:59
    
I don't think any of the standard garbage collectors shipped with the JVM support pauseless GC yet - the pause is shorter but not gone. Some are working on pauseless GC: infoq.com/news/2010/09/bigmemory en.wikipedia.org/wiki/Azul_Systems Also here's a StackOverlow thread that mentions the deallocation method I referred to: stackoverflow.com/questions/390102/… –  greg May 22 '12 at 12:05
1  
Depends on which JVM you use. We use a non-x86 IBM JVM for production, which can do pauseless gc. –  user1249 May 22 '12 at 12:07
8  
The newer Java versions from Oracle can do escape analysis, which means that objects that don't escape a method are allocated on the stack, which makes cleaning them up free - they are automatically deallocated when the method returns. –  Jesper May 22 '12 at 14:37
1  
@Mehrdad - it runs in parallel without pausing the JVM. It does - however - stop the world if the gc cannot keep up (a gc is requested before the previous gc has finished). This usually happens only when swapping badly. –  user1249 May 23 '12 at 7:48
show 9 more comments

There is one case where you may be discouraged from creating too many objects in Java because of the overhead - designing for performance on the Android platform

Other than that, the above answers hold true.

share|improve this answer
    
Read the question again. It does not specify JVM anywhere including the tags. It only mentions Java. –  Peter Kelly May 22 '12 at 15:08
add comment

This really depends on the specific application, so it's really hard to say in general. However, I would be pretty surprised if object creation was actually a performance bottleneck in an application. Even if they are slow, the code-style benefit will probably outweigh the performance (unless it's actually noticeable to the user)

In any case, you shouldn't even start to worry about these things until you have profiled your code to determine the actual performance bottlenecks instead of guessing. Until then, you should do whatever is best for code readability, not performance.

share|improve this answer
    
In early versions of Java there was a substantial cost incurred when the garbage collector cleaned up discarded objects. Recent versions of Java have greatly enhanced GC options, so object creation is rarely an issue. Usually web systems are limited by IO calls to external systems unless you're computing something truly complex on the application server as part of the page load. –  greg May 22 '12 at 2:18
add comment

the GC is tuned for many short lived object

that said if you can trivially reduce object allocation you should

one example would be building a string in a loop, the naive way would be

String str = "";
while(someCondition){
    //...
    str+= appendingString;
}

which creates a new String object on each += operation (plus a StringBuilder and the new underlying char array)

you can easily rewrite this into:

StringBuilder strB = new StringBuilder();
while(someCondition){
    //...
    strB.append(appendingString);
}
String str = strB.toString();

this pattern (immutable result and a local mutable intermediate value) can be applied to other things as well

but other than that you should pull up a profiler to find the real bottleneck instead of chasing ghosts

share|improve this answer
    
the biggest advantage in this StringBuilder approach is the pre-size the StringBuilder so that it never has to reallocate the underlying array with the StringBuilder(int) constructor. This makes it a single allocation, rather than a 1+N allocations. –  Jarrod Roberson May 22 '12 at 18:11
    
@JarrodRoberson StringBuilder will at least double the current capacity or in other words the capacity will grow exponentially for only log(n) allocations –  ratchet freak May 22 '12 at 19:09
add comment

There's more to creating a class than allocating memory. There's also initialization, I'm not sure why that part is not covered by all the answers. Normal classes contain some variables, and do some form of initialization, and that isn't free. Depending on what the class is, it may read files, or do any other number of slow operations.

So just consider what the class constructor does, before figuring if it's free or not.

share|improve this answer
1  
A well-designed class shouldn't do heavy-lifting in its constructor, for just this reason. For example, your file-reading class could lower its cost of instantiation by only verifying that its target file exists on startup, and deferring any actual file operations until the first method call that needs data from the file. –  GordonM May 24 '12 at 6:00
1  
If the additional cost is moved to the 'if (firstTime)', than recreating class in a loop is still more expensive than reusing the class. –  Alex May 24 '12 at 14:19
add comment

I think your colleague must have said from the perspective of unnecessary object creation. I mean if you are creating the same object frequently then it is better to share that object. Even in cases where object creation is complex and takes more memory, you might want to clone that object and avoid creating that complex object creation process(But that depends on your requirement). I think the statement "Object creation is expensive" should be taken in context.

As far as JVM memory requirements are concerned, wait for Java 8, you don't even need to specify -Xmx, meta space settings will take care of JVM memory need and it will grow automatically.

share|improve this answer
    
It would be very constructive if people put comment also while down voting any answer. After all we are all here to share knowledge, and simply passing judgment without proper reason is not going to serve any purpose. –  AKS Aug 2 '13 at 11:33
1  
Stack exchange should have some mechanism to notify users who down vote any answer, when comment is posted on that answer. –  AKS Aug 2 '13 at 16:46
add comment

As people have said object creation is not a big cost in Java (but I bet bigger than most simple operations like adding, etc) and you shouldn't avoid it too much.

That said it still a cost, and sometimes you may find yourself trying to scrap as many object as possible. But only after profiling has shown that this is a problem.

Here is a great presentation on the topic: https://www.cs.virginia.edu/kim/publicity/pldi09tutorials/memory-efficient-java-tutorial.pdf

share|improve this answer
add comment

protected by Yannis Rizos Aug 2 '13 at 5:39

Thank you for your interest in this question. Because it has attracted low-quality answers, posting an answer now requires 10 reputation on this site.

Would you like to answer one of these unanswered questions instead?

Not the answer you're looking for? Browse other questions tagged or ask your own question.