Java Memory Management With example

LearnNewTech
4 min readJan 18, 2022

JAVA MEMORY MANAGEMENT

To run an application in an optimal way, JVM divides memory into stack and heap memory. Whenever we declare new variables and objects, call a new method, declare a String, or perform similar operations, JVM designates memory to these operations from either Stack Memory or Heap Space.

Java Stack memory

Sample Code

Java Stack memory is used for the execution of a thread. They contain method-specific values that are short-lived and references to other objects in the heap that is getting referred from the method.

Let’s go through the steps of the execution of the program.

  • As soon as we run the program, it loads all the Runtime classes into the Heap space. When the main() method is found at line 1, Java Runtime creates stack memory to be used by main() method thread.
  • We are creating primitive local variable at line 2, so it’s created and stored in the stack memory of main() method.
  • Since we are creating an Object in the 3rd line, it’s created in heap memory and stack memory contains the reference for it. A similar process occurs when we create Memory object in the 4th line.
  • Now when we call the foo() method in the 5th line, a block in the top of the stack is created to be used by the foo() method. Since Java is pass-by-value, a new reference to Object is created in the foo() stack block in the 6th line.
  • A string is created in the 7th line, it goes in the String Pool in the heap space and a reference is created in the foo() stack space for it.
  • foo() method is terminated in the 8th line, at this time memory block allocated for foo() in stack becomes free.
  • In line 9, main() method terminates and the stack memory created for main() method is destroyed. Also, the program ends at this line, hence Java Runtime frees all the memory and ends the execution of the program.

Difference between Java Heap Space and Stack Memory

Based on the above explanations, we can easily conclude the following differences between Heap and Stack memory.

  1. Heap memory is used by all the parts of the application whereas stack memory is used only by one thread of execution.
  2. Whenever an object is created, it’s always stored in the Heap space and stack memory contains the reference to it. Stack memory only contains local primitive variables and reference variables to objects in heap space.
  3. Objects stored in the heap are globally accessible whereas stack memory can’t be accessed by other threads.
  4. Memory management in stack is done in LIFO manner whereas it’s more complex in Heap memory because it’s used globally. Heap memory is divided into Young-Generation, Old-Generation etc, more details at Java Garbage Collection.
  5. Stack memory is short-lived whereas heap memory lives from the start till the end of application execution.
  6. We can use -Xms and -Xmx JVM option to define the startup size and maximum size of heap memory. We can use -Xss to define the stack memory size.
  7. When stack memory is full, Java runtime throws java.lang.StackOverFlowError whereas if heap memory is full, it throws java.lang.OutOfMemoryError: Java Heap Space error.
  8. Stack memory size is very less when compared to Heap memory. Because of simplicity in memory allocation (LIFO), stack memory is very fast when compared to heap memory.

Adjusting JVM memory settings

In general, you should allocate as much memory as possible to the JVM running your application server. You can do this by setting the JVM memory configuration.

To set the JVM memory configuration:

  • -Xmx should be between 80% and 100% of the machine’s physical memory. If you set -Xmx too small, the application server may fail with an OutOfMemory error. If you set -Xmx too large, the memory’s footprint is larger and you run the risk of the Java™’s heap being swapped out, causing other performance problems.
  • -Xms should be approximately half of the -Xmx setting. If you have historical data about your application server’s stable memory-usage point, then set -Xms to be around that value.
  • Another option is to set -Xms to the memory-usage value observed at the end of InitServlet.This will ensure that, at a minimum, DEBS initialization will complete with as little garbage collection as possible. To get the memory usage value, perform the following steps:

--

--