Low GC in Java: Use primitives instead of wrappers
OverviewThere are two good reason to use primitives instead of wrappers where possible.
- Clarity. By using a primitive, you are making it clear that a null value is not appropriate.
- Performance. Using primitives is often much faster.
I have had a lot of interest in this article How to avoid Garbage Collection, however this was lacking in much practical detail. This is the first article in a series on ways to reduce demands on the GC.
A followup article Low GC in Java: Using primitives looks at using primitives and collections which support them.
Performance of using wrappersThe following micro-benchmark behaves in a way many application do.
This creates objects for each task. While it is common practice to use int for loop counters its is also common practice to use Iterator You can play around with the types and parameters of this micro-benchmark, however you get a memory profile which will be familiar to many developers who have tried to tune their application. Using VisualVM the heap usage looks like this over a five minute period.
The average time of each loop is sub-microsecond which is pretty fast.
Took 4,099 ns per loop Took 559 ns per loop Took 115 ns per loop Took 240 ns per loop Took 255 ns per loopIn the first test, the JVM hasn't warmed up.
Can using primitives really make much difference?
Performance of using primitivesThe following benchmark behaves rather differently to most applications. Even though it is doing the same work as the previous benchmark, there is no objects created.
and the heap usage reflects this
And the average time per loop is much lower as well
Took 198 ns per loop Took 17 ns per loop Took 16 ns per loop Took 14 ns per loop Took 15 ns per loopIn the first test, the JVM hasn't warmed up.
ConclusionUsing primitives will perform better. (Unless there is excessive boxing and unboxing)
Even in applications where performance is not critical, it will improve clarity, both of the code and when you do attempt to profile your application, it will reduce the level of "noise" making it clearer as to what the problem is.
NotesEven in the test where few objects were created, you can see some object allocation. This is mostly due to VisualVM's polling. To reduce this I changed the polling interval from 3 seconds to 20 seconds.
The Eden size was increased to make the graphs clearer with -XX:NewSize=100m This value is not recommend (except perhaps for micro-benchmarks) but its is a parameter you may need to tune for your application.
Full codePrimitive benchmark