How does Memory work on Java

One of the major advantages of Java since its first version was that developers didn’t have to worry about memory, as Java itself was able to keep it clean and free memory automatically. But any good Java developer should know the basics on how Java handles memory to be prevent memory leaks and bottlenecks.

To begin with, Java divides memory into two distinct segments:

  • Heap: instances, variables, …
  • Non-Heap/Perm: code, metadata,…

As the first step to optimize memory in Java, we should focus on the Heap, as it is what we can “control”. The Heap is divided in two generations depending on their lifetime:

  • Young Generation
  • Old Generation

Usually the Young generation is composed of local variables and temporary objects. While the older generation contains structures that are needed during the execution like configurations.

The younger generation is divided into two:

  • Eden: This is where objects are created initially
  • Survivor: It’s like the limbo through which we pass from the Young to the Old generation.

The Garbage Collector

The Garbage Collector is the system making sure the memory is clean. It performs two types of periodic tasks:

  • Minor Collection: Reviews quickly the younger generation.
  • Major Collection: Reviews all the memory, mainly the older generation.

The garbage collector runs at the same time as the normal program execution. Each execution involves a small pause (usually milliseconds) in all the threads that are running at that time. While your application memory remains healthy, the Garbage Collector will limit its actions to minor collections, to not interfere with the flow of the application.

Different memory strategies

There are several implementations of the garbage collector, being the most common the Serial Collector. This implementation, as well as being the simplest, uses only one processor. If you’re using a more powerful machine with multiple processors and a good amount of physical memory, you can activate the Parallel Collector , which uses multiple CPUs at the same time. This improves the way in which the garbage collector works. It can also parallelize the flow of normal execution of the application.

For proper operation and cleaning of memory, we should have little short-lived temporary objects better than long, durable objects. The small temporary objects will stay in the Eden, so they will be collected much earlier and much faster.

Also, having unused objects in memory, although they do not disrupt the execution of the program, will slow the execution of the garbage collection. Because you have to process them over and over again to check if they can be deleted.

At some point it may seem tempting to force a Garbage Collector implementation calling System.gc(). However, this will force a major collection asynchronously, breaking up all the heuristics of the Garbage Collector and stopping your application while it lasts. It is so discouraged that there is an option in the virtual machine to disable these calls: -XX:+DisableExplicitGC

References

To help the task of garbage collection, there are three types of references when defining objects:

  • Weak : It does not prevent the GC to clean it.
  • Soft : The GC respects a little and removes the instance only if memory is needed. Useful for caching, but can be misleading.
  • Phantom: Always returns null. The link doesn’t really point to the object. Can be used to clear instances before taking the object that binds it.

For example we can use WeakHashMap, which works as a HashMap, but using weak references. So, if the key contains an object which is only referenced in the map, it is no longer considered useful and is removed.

Author: María Arias de Reyna Domínguez

This is the blog of María Arias de Reyna.

4 thoughts on “How does Memory work on Java”

  1. Excelente post, te felicito, me acabas de sacar de muchas dudas. Saludos desde Colombia.

Leave a Reply

Your e-mail address will not be published. Required fields are marked *

en_GBEnglish (UK)