Java has been considered a mature and robust programming language and one of the reasons is its excellent features for memory management. There are several options for memory management in Java that ensure the stable running of applications. This will be a complete guide to understand memory management in Java. We will be covering some important topics like how the heap works, reference types, and garbage collection.
Table of Contents
You might be wondering, why would a programmer need to know about the working of memory? Java, like any other modern high-level language, has automatic memory management and an efficient garbage collector that cleans up all the unused objects and manages the memory implicitly.
It is correct that a Java developer does not need to perform any memory-related tasks but by not knowing how the garbage collector works and how Java memory is managed, you could end up collecting objects that are not eligible for garbage collecting, even if you no longer need them.
Knowing how to manage memory in Java allows you to write high-performing and optimized codes that will not crash with an OutOfMemoryError and if you ever encounter a memory-related error, you will be able to identify the problems.
Memory is divided into two big chunks in Java: one is the stack and the other is the heap.
Stack memory is mainly responsible for containing all the references to objects present in heap memory and for storing actual values of primitive data types.
Variables in the stack memory have certain visibility, known as scope. Objects with the active scope are the only ones used by the methods. For instance, if you do not have any global scope variables and just the local variables in your method when it will be executed by the compiler, it can only access the objects from the stack that are present within the method’s body. It cannot access other local variables, as those are out of scope. Once the method is executed and it returns the result, the active scope will now change as the top of the stack pops out.
It is to be noted that the stack memory in Java is allocated for every individual thread. It means that whenever a thread is created and started, it gets a new share of stack memory.
Heap is where the actual objects are stored in the memory. As the name suggests, it’s just like a heap and does not have a certain structure like the stack that’s why the objects are then referred to by the variables present in the organized stack memory. For example, see the following line of code:
int arrayResult[] = new int[6];
The “new” keyword ensures that there is enough space available in the heap, then it creates an object of the array of integers in memory and refers to it via the “arrayResult” reference, which is then stored in the stack. Unlike the stack memory, there is only one heap memory for every JVM process. Therefore, it is a shared part of memory regardless of how many threads are running at a time.
When it comes to references, there are different types of references in the Java programming language. Let’s take a look at each of them.
It is the most commonly used reference type and is the default reference to objects in the heap. The example above holds a strong reference to the object from the heap. The strong reference indicates that the object will not be eligible for garbage collection while there is a strong reference pointing to it.
On the contrary to Strong referencing, Weak Reference Objects are not the default type of Reference objects and they must be explicitly specified when used. a weak reference to an object is most likely used to clean the object in the next garbage collection process. A weak reference can be created as follows:
WeakReference<int arrayResult[]> reference = new WeakReference<>(new int[6]);
Soft referencing is used for memory-sensitive scenarios, The soft referred objects will be only garbage collected when your application is running low on memory. Therefore, as long as there is no critical need to free up some space, the garbage collector will not touch soft referred objects.
Similar to weak references, a soft reference is created as follows:
SoftReference<int arrayResult[]> reference = new SoftReference<>(new int[6]);
The objects which are being referred by phantom references are eligible for garbage collection but before deletion, JVM puts them in a queue called ‘reference queue’. It is done after calling the finalize() method on them, that is why the .get() method of such references always returns null as the object is no longer in the heap.
Garbage collection is an integral part of memory management in Java. A garbage collector automatically finds the unused objects in the heap and deletes them to free up memory.
Garbage collectors follow the following series of steps.
The compaction process makes it convenient to allocate memory to new objects in a sequence after the block of memory is allocated to existing objects.
Following are some of the important points around memory management in Java regarding the Garbage collection process,
being a quite complex process, JVM has three types of garbage collectors. By default, Java itself chooses the garbage collector type to be used depending on the hardware but the java developers have the option to choose which one should be used.
Following are the three types of Garbage collectors,
It is a single thread collector, mostly used for small applications with minor data usage.
As the name suggests, the parallel GC uses multiple threads at a time to perform the garbage collecting process. It is also known as a throughput collector and due to its better performance, it is a better choice for applications with moderate data usage.
It is the most expensive garbage collector of all as it pauses all threads when executed. The reason why it is “mostly” concurrent is that it does not work concurrently with the applications. There is a specific period for which the threads are paused which is kept as short as possible to achieve the best GC performance and keep it least expensive.
There are 2 further types of mostly concurrent GC:
1.1 Garbage First – It has high throughput with a reasonable amount of application pause time.
1.2 Concurrent Mark Sweep – In this GC, the least application pause time is prioritized and is kept to a minimum as much as possible.
Understanding how memory management works in Java will give you the advantage of writing efficient and optimized programs. You can now configure your JVM using the most suitable configuration for your running application and identify memory issues and leaks easily.
See Also: Top Java Developing Tools And Software
Shaharyar Lalani is a developer with a strong interest in business analysis, project management, and UX design. He writes and teaches extensively on themes current in the world of web and app development, especially in Java technology.
Create a free profile and find your next great opportunity.
Sign up and find a perfect match for your team.
Xperti vets skilled professionals with its unique talent-matching process.
Connect and engage with technology enthusiasts.
© Xperti.io All Rights Reserved
Privacy
Terms of use