Tag Archives: Java performace

How to slim down your Java

Episode 16

This article is the second part of my Java performance guide. After concentrating on how to make code fast, let’s turn to how to make code eat less memory. There are two important things to consider:

First, in modern computers, memory access time is more limiting than CPU frequency.

Second, when talking about algorithms from academic point of view, it is said, that there is a tradeoff between speed and memory. That’s of course true, however keep in mind, that memory allocation takes time, memory read/write takes time and finally garbage collection takes time. If you turn on heap status in Eclipse, you can sometimes literally see how the code is reaching 99% percent of the heap and then execution time hits the wall and things slows down a lot. GC is working hard to make things possible. If it is possible, otherwise you are getting OutOfMemoryError and you are done.


Java, wat r u doin! Java, staph…

Of course, you can increase heap space to make things happen. However you can’t do that indefinitely (unless you are Google). Although one of my PO’s said once that we shouldn’t worry because clients have unlimited memory, you should worry. Not always, and maybe not even half the time, but being reckless with memory might hit you hard in some particular cases.

Code that is memory efficient might be complicated, hard to maintain and error prone, but there are few thing you can keep in mind and use without introducing unnecessary complications. Sometimes, as I said in previous article, code that is faster or takes less memory may be even more elegant and readable.

So when to optimize size?

Again, get to know your code. Study, experiment, check out the production database (if you have access), do some statistics. If you have a collection containing all your users, check out how much user you have. If it’s a problem, look for high level solution. Perhaps you don’t need all users at one time? Maybe you can process them in batches? Maybe you can load lazily? Maybe you can construct some kind of cache?

If this approach fails, you can tweak stuff at lower level of abstraction, and that’s what we are going to discuss now.

Objects size

Object header in Java takes 12 bytes. However objects on heap are allocated in 8 bytes blocks, thus making smallest Objects take 16 bytes. Primitive sizes are:

  • byte – well, 1 byte
  • short, char – 2 bytes
  • int, float – 4 bytes
  • long, double – 8 bytes
  • Reference – 4 bytes if heap is under 32 GB with default VM settings and 8 bytes otherwise.

So if you are thinking of reducing your object size from 32 to 28 or 26 bytes, I have bad news for you. It will still take 32 bytes no matter what.

byte and short pitfall

Primitives as objects fields always take a minimum of 4 bytes. So using bytes or shorts instead of ints as fields to save memory is useless. Arrays however are dense packed, so you may use byte and short array to get some savings.

Primitives vs wrappers

Wrappers carry the Object overhead. They take at least 16 bytes, and Long and Double takes 24. Plus 4 bytes for each reference to them. If you have a lot of data, and don’t need a null value, you can use primitives instead of wrappers to save memory. For example in a User object, if you only read data from database, you can probably use long instead of Long for primary key and save 16 bytes per object. On the other hand, if you use ORM framework, you may create objects by hand and then persist them, which means that primary key will be null at some point.


  • Primitive array of length n: 16 + (1 to 8) * n depending on primitive type.
  • Objects arrays: 16 + (4 + object_size) * n on heap below 32 GB.


Each String contains a few ints, a reference to char array and the array itself. It all takes 40 + 2*n depending on number of characters. What does it mean? If you have a lot of very short Strings, you have a lot of overhead. If you have only one-letter strings, it’s probably better to use chars instead.


Now it’s getting interesting.

  • ArrayList: 40 + (4 +object_size) *n + 4 * unused_capacity
  • LinkedList: 48 + (24 + object_size)

Yes, LinkedList has 6 times more overhead per node. That’s another reason to use ArrayList instead most of the time. Array list resizes itself automatically, so it usually has some unused space. If you know that no more data will be added, you may use it’s trimToSize method to remove unnecessary overhead. Not very much, but with lots of small objects it might be visible.


  • HashMap: 56 + (32 + object_size + key_size) * n + 4 * capacity
  • LinkedHashMap: 56 + (40 + object_size + key_size) * n + 4 capacity
  • TreeMap: 56 + (40 + object_size + key_size) * n + 4 * capacity

I had a situation where there was a graph node object, that contained several eagerly initialized collections, that were empty 95% of the time. It turns out that when number of nodes went in millions, it was a serious problem. Creating collections lazily might save you some space.

By the way, Sets in Java contains Maps, so they have same size per node, with additional overhead per Set Object.


There are libraries of specialized collections, like Trove. They are optimized for memory footprint. For example THashMap takes only 8 bytes per key / value pair instead of 40 as standard HashMap

EnumMap, EnumSet – specialized collection in standard Java. As, most of the time, Enums do not have more than 32 or 64 values, Set of enums may be represented as bit mask based on int or long. It reduces a lot of overhead for MapEntry objects.

BitSet. Dense packed bit vector, that only takes, well, only 1 bit per bit or boolean value. Normal boolean in Java occupies 4 bytes if it’s a variable or 1 byte if it’s in an array.

What’s next?

Perhaps I will come back to the topic of performance. I have a new book, Java Performance The Definitive Guide added to my long reading list. I hope it will be interesting and third episode about performance will be born on this blog afterwards.

Speaking of reading list, next episode is going to be a book review. Stay tuned ;)


Leave a comment

Posted by on September 28, 2014 in Clean Code, Technology


Tags: ,

Lightning Fast Code

Entry 15, Day 51

As promised, today’s episode is going to be about low-level optimization. First, a quote.

„Premature optimization is the root of all evil”

   – Donald Knuth

Yes indeed. We all love when things go faster than slower, but deadlines are tight and working, stable software with acceptable performance is better than software which is fast but unstable or not working at all. There is no point in tuning your Java computation to take 5 milliseconds instead of 50, when you are going to wait for database query that takes 5 seconds (optimize the query, maybe?). Also, in case of web application, there will be network latency of tenths or hundreds of milliseconds. Another issue is code readability. Sometime, to run faster, the code has to be more complicated and that’s always pain in the ass…


So when to optimize?

First, get to know your API. There are many small problems, that are already solved by standard Java library. And solved well, for example using Read the rest of this entry »


Posted by on September 21, 2014 in Clean Code, Sweet Sixteen, Technology


Tags: ,