Memory Allocation with Java

memory allocation java

Every time we create a variable, invoke a method, or create an instance memory allocation will happen in Java and any other programming language. Data is stored in the form of bits, each memory slot can hold 1 byte which is the same as 8 bits.

Let’s see the chart of how many bits each variable from Java uses:

Type
boolean 1 bit false, true
byte 1 byte -128 to 127
short 2 bytes 0 (‘\u0000’) to 65535 (‘\uffff’)
char 2 bytes -32768 to 32767
int 4 bytes -2147483648 to 2147483647
long 8 bytes 1-9223372036854775808 to 9223372036854775807
float 4 bytes 1.40239846e-45f to 3.40282347e+38f
double 8 bytes 4.94065645841246544e-324 to 1.79769313486231570e+308

Data in Binary Number

Computers only understand binary numbers, therefore, every data stored in memory will be transformed into a binary number. A binary number is a number with a base 2 which means that the data must be represented by only 0 or 1.

The int number for example has 4 bytes which translates to 32 bits. Let’s see how the decimal number 1 is represented by a binary number:

public class BinaryRepresentation {

  public static void main(String[] args) {
    int number1 = 1;
    int number10 = 10;

    showBinaryNumber(number1);
    showBinaryNumber(number10);
  }

  private static void showBinaryNumber(int number) {
    var binaryNumber = String.format("%32s", Integer
                        .toBinaryString(number)).replace(' ', '0');
    System.out.println(binaryNumber);
  }

}

Output:
00000000000000000000000000000001
00000000000000000000000000001010

The zeros on the left don’t make any impact in a binary number but I added the zeros on the left to show you that an int value has 32 bits and that’s the space that will be taken in the memory slot.

Since creating a variable, and invoking a method are elementary operations the computer is able to find a memory slot given the memory address very quickly.

Contiguous Memory Slots Allocation

As mentioned before, each memory slot holds 1 byte. Let’s see in the following diagram the representation of how a boolean, short, int, and double types are stored in memory:

Memory Allocation

Array Allocation

An array also needs to have data allocated contiguously meaning that if there is an array of boolean with 10 elements, these arrays need to occupy 10 bytes, it can’t be broken. Otherwise, it would impossible to have quick access to its elements.

Now, remember that the boolean type takes 1 bit but each memory slot only stores 1 byte. The JVM (Java Memory Model) also avoids word tearing which basically forces values not to be broken down into the same memory slot. Also, word tearing should avoid changing multiple fields in the same memory slot.

Therefore, each boolean value will hold 1 byte of space, other than that, we will need 10 contiguous bytes to allocate an array of 10 boolean values. Internally the JVM will store more bytes for the array. We don’t need to know this in detail but if you are curious you can run your own tests with the library JOL (Java Object Layout).

Since an array in Java is an object, there will be extra bytes space because the JVM will allocate in memory called as object header.

In the header, there is the mark word memory allocation which will store the Garbage Collector metadata, identity hashcode, and locking information which takes around 8 bytes.

Klass is part of the header too and it’s used to store class metadata, the JVM will use 4 bytes for that. Also, there is the extra space of memory the JVM will allocate for the array length.

The JVM will allocate approximately 17 extra bytes when creating an array object.

However, there is no need to know that in detail, the most important thing you must remember is that arrays will take memory space contiguously. You can learn more about arrays in the article Array Data Structure with Java.

Therefore, let’s see how an array of 10 elements would be represented NOT considering the extra space the JVM will create for the array object:

boolean array

Static Memory Allocation

Static memory is the stack memory in Java. The stack memory is used to allocate space from local variables, and methods invocations in the LIFO (Last-in Last-out) style.

A very important point from the stack memory is that when a method finishes its execution the variable and the method will be removed from the stack. When using the stack memory there won’t be problems with threads collisions because each thread has its own stack.

Also, the access pattern from the stack is easy enough to allocate and deallocate memory it is faster than the dynamic memory (heap memory).

Dynamic Memory Allocation

The dynamic memory in Java is the heap memory. The heap memory is used to store objects and the references of these objects are stored in the stack memory.

The heap memory can be accessed globally in the application. It’s also more complex than the stack memory. In the heap memory, objects need to be collected non-used objects by the Garbage Collector. Also, since the objects are shared in the application, the heap memory is not thread-safe.

Summary

The main focus of this article is to show you how variables and methods are stored in memory, not necessarily to show you how the Java memory model works, this would be a whole article or book itself.

Let’s see the key points of this article:

  • Each memory slot holds 1 byte.
  • 1 byte is the same as 8 bits.
  • boolean stores 1 bit but will be stored in 1 byte to avoid having different data in the same memory slot.
  • Every variable value behind the scenes becomes a binary number so the computer can understand it.
  • An array will occupy memory space contiguously, this means data has to be stored from back to back.
  • An array in Java will occupy more space in memory due to the internal JVM configurations.
  • The static memory in Java is the stack memory.
  • The stack memory will keep methods and variables alive until they are finished. It’s also thread-safe.
  • The dynamic memory in Java is the heap memory.
  • The heap memory in Java is more complex and it’s mainly responsible to manage instances of objects.
Written by
Rafael del Nero
Join the discussion