Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / DevOps

Java & Struct/Value Type Benefits & How to Obtain Them

5.00/5 (1 vote)
27 Apr 2018CPOL2 min read 6.4K  
Introduction to structs (value types) in Java

Introduction

If you are familiar with structs (value types), you may have wondererd why Java does not support them yet. While objects in Java are great for common usage, in those cases where performance and memory really matters, structs would be ideal.

Background

To illustrate the benefits of value types, consider the following:

Java
int[] arrayA = new int[1000];
Integer[] arrayB = new Integer[1000];

Both arrayA and arrayB store 1000 integers. Since each integer in Java takes 4 bytes, the total storage should be close to 4000 bytes. For arrayA, this is true, including the array header, arrayA takes approximately 4016 bytes. However, things are not similar for arrayB, which stores an array of references to objects. ArrayB takes 20016 bytes assuming each reference takes four bytes.

What if we have a class representing a vector?

Java
class Vector2f { float x, y; }
Vector2f[] arrayVec = new Vector2f[1000];

We are interested in storing 1000 vectors, which should ideally take about 8000 bytes of memory.

However, since Vector2f is a class, we get to a similar issue as with the int and Integer. ArrayVec takes ~28016 bytes, which is a lot more from the original 8000 which will be used by our application.

Not only memory, but also performance is affected by the object overhead as the processor will have to load a lot more data. We could store the thousand vectors in a primitive array, however, what can we do for data such as?

Java
class Star { int id; double x, y; float absMag; }
Star[] starArray = new Star[1000];

Each star has 24 bytes of data, with object header of 12 bytes we get 36 bytes and with alignment 40 bytes. Star array takes ~44016 bytes.

We could store the star data as:

Java
int[] starId = new int[1000];
double[] starXY = new double[2000];
float[] starAbsMag = new float[1000];

This would bring the memory usage down to 24048 bytes. However, how readable and maintainable would our code look like.

Luckily, there is an alternative.

Using the Code

With the help of an open source library JUnion, we can write the following:

Java
@Struct
class Star { int id; double x, y; float absMag; }
Star[] starArray = new Star[1000];

Since Star is no longer an object, starArray uses ~24040 bytes.
We can use the struct type Star in a very similar way as we use Java objects. There are few distinctions such as struct array elements that are not initialized with constructors as normal object arrays are.

Java
Star[] starArray = new Star[1000];
starArray[5].id = 10;
Star s5 = star[5];
...

If Star was an object, the above code would throw a NullPointerException. This is not the case for struct types.

To use struct types, you will require https://github.com/TehLeo/junion.

Conclusion

This article introduces struct/value types and their benefits of lower memory usage over objects.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)