{"id":73668,"date":"2025-08-04T21:14:52","date_gmt":"2025-08-04T15:44:52","guid":{"rendered":"https:\/\/www.tothenew.com\/blog\/?p=73668"},"modified":"2025-09-17T11:48:44","modified_gmt":"2025-09-17T06:18:44","slug":"java-memory-management-and-garbage-collection-explained","status":"publish","type":"post","link":"https:\/\/www.tothenew.com\/blog\/java-memory-management-and-garbage-collection-explained\/","title":{"rendered":"Java Memory Management and Garbage Collection Explained (Part 1)"},"content":{"rendered":"<h2>Introduction<\/h2>\n<p>Java memory management refers to the process by which the Java Virtual Machine (JVM) allocates, organizes, and reclaims memory used by variables, methods, classes, and objects during program execution. It ensures efficient memory use by automatically managing object creation and destruction, helping developers avoid manual memory handling and common pitfalls like memory leaks.<\/p>\n<h2>Types of Memory<\/h2>\n<p>In Java, memory is mainly divided into two core regions: the <strong>Heap<\/strong> and the <strong>Stack<\/strong>.<\/p>\n<p>Both are managed internally by the JVM to ensure efficient execution and memory allocation for various program components.<\/p>\n<h3>Stack Memory :<\/h3>\n<p>Stack memory is a section of JVM memory that holds method call information along with their local variables. It follows the Last-In-First-Out (LIFO) principle, meaning the most recently called method is the first to be removed once execution completes.<\/p>\n<p><strong>Stack memory is used to store:<\/strong><\/p>\n<ul>\n<li>Basic <strong>primitive data types<\/strong> such as int, long, double, and others.<\/li>\n<li><strong>References<\/strong> to objects that reside in the heap memory<\/li>\n<\/ul>\n<p>Additionally, variables in the stack have a <strong>specific scope <\/strong>\u2014 which defines where they are accessible. Whenever a method is invoked, the JVM creates a new stack frame to hold its local variables. These variables live only within the method\u2019s scope and are cleared from the stack when the method completes.. Once the method completes, its frame is removed from the stack, and all associated variables are cleared. Control then returns to the calling method, restoring its stack frame and scope.<\/p>\n<h3>Heap Memory :<\/h3>\n<p>Within the JVM, the heap is used to hold <strong>all instances<\/strong> <strong>of objects<\/strong> that are created while the application runs. These objects are referenced by variables that reside in <strong>stack memory.<\/strong><\/p>\n<p>Let&#8217;s take a simple example:\u00a0<strong>User userObj = new User();<\/strong><\/p>\n<p>Here\u2019s what happens:<\/p>\n<ul>\n<li>Using the <strong>new<\/strong> keyword instructs the JVM to reserve memory in the heap for a newly created User object.<\/li>\n<li>The object is created in heap memory.<\/li>\n<li>A reference to that object is stored in the stack under the variable <strong>userObj<\/strong>.<\/li>\n<\/ul>\n<p>The heap is a unified memory area shared across all threads within a JVM instance. This makes it essential to handle object access carefully in multi-threaded environments. Whereas <strong>S<\/strong><strong>tack memory is created per thread<\/strong>. Every thread maintains its own separate stack, which keeps method calls and local variables isolated from those of other threads.<\/p>\n<div id=\"attachment_73671\" style=\"width: 635px\" class=\"wp-caption alignnone\"><img aria-describedby=\"caption-attachment-73671\" decoding=\"async\" loading=\"lazy\" class=\"size-large wp-image-73671\" src=\"https:\/\/www.tothenew.com\/blog\/wp-ttn-blog\/uploads\/2025\/07\/ThreadWiseMemory-1-1024x731.png\" alt=\"Diagram showing the relationship between stack and heap memory in Java.\" width=\"625\" height=\"446\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2025\/07\/ThreadWiseMemory-1-1024x731.png 1024w, \/blog\/wp-ttn-blog\/uploads\/2025\/07\/ThreadWiseMemory-1-300x214.png 300w, \/blog\/wp-ttn-blog\/uploads\/2025\/07\/ThreadWiseMemory-1-768x548.png 768w, \/blog\/wp-ttn-blog\/uploads\/2025\/07\/ThreadWiseMemory-1-1536x1096.png 1536w, \/blog\/wp-ttn-blog\/uploads\/2025\/07\/ThreadWiseMemory-1-2048x1461.png 2048w, \/blog\/wp-ttn-blog\/uploads\/2025\/07\/ThreadWiseMemory-1-624x445.png 624w\" sizes=\"(max-width: 625px) 100vw, 625px\" \/><p id=\"caption-attachment-73671\" class=\"wp-caption-text\">Diagram showing the relationship between stack and heap memory in Java.<\/p><\/div>\n<p><strong>Example :\u00a0<\/strong><\/p>\n<div id=\"attachment_73662\" style=\"width: 635px\" class=\"wp-caption alignnone\"><img aria-describedby=\"caption-attachment-73662\" decoding=\"async\" loading=\"lazy\" class=\"size-large wp-image-73662\" src=\"https:\/\/www.tothenew.com\/blog\/wp-ttn-blog\/uploads\/2025\/07\/Screenshot-from-2025-07-27-23-13-33-1024x490.png\" alt=\"Java source code example showing the creation of primitive variables, string literals, and objects. The code illustrates how variables in stack memory reference objects stored in heap memory, including instances of MemoryManagement and User classes.\" width=\"625\" height=\"299\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2025\/07\/Screenshot-from-2025-07-27-23-13-33-1024x490.png 1024w, \/blog\/wp-ttn-blog\/uploads\/2025\/07\/Screenshot-from-2025-07-27-23-13-33-300x143.png 300w, \/blog\/wp-ttn-blog\/uploads\/2025\/07\/Screenshot-from-2025-07-27-23-13-33-768x367.png 768w, \/blog\/wp-ttn-blog\/uploads\/2025\/07\/Screenshot-from-2025-07-27-23-13-33-624x298.png 624w, \/blog\/wp-ttn-blog\/uploads\/2025\/07\/Screenshot-from-2025-07-27-23-13-33.png 1173w\" sizes=\"(max-width: 625px) 100vw, 625px\" \/><p id=\"caption-attachment-73662\" class=\"wp-caption-text\">Java code snippet demonstrating how variables in stack memory reference objects in heap memory, including primitives, string literals, and user-defined objects.<\/p><\/div>\n<div id=\"attachment_73661\" style=\"width: 635px\" class=\"wp-caption alignnone\"><img aria-describedby=\"caption-attachment-73661\" decoding=\"async\" loading=\"lazy\" class=\"size-large wp-image-73661\" src=\"https:\/\/www.tothenew.com\/blog\/wp-ttn-blog\/uploads\/2025\/07\/ObjectReferences-1024x473.png\" alt=\"Diagram showing a Java variable stored in stack memory referencing an object located in heap memory. The image includes method call frames in the stack and objects in the heap, connected by reference arrows.\" width=\"625\" height=\"289\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2025\/07\/ObjectReferences-1024x473.png 1024w, \/blog\/wp-ttn-blog\/uploads\/2025\/07\/ObjectReferences-300x139.png 300w, \/blog\/wp-ttn-blog\/uploads\/2025\/07\/ObjectReferences-768x355.png 768w, \/blog\/wp-ttn-blog\/uploads\/2025\/07\/ObjectReferences-1536x710.png 1536w, \/blog\/wp-ttn-blog\/uploads\/2025\/07\/ObjectReferences-2048x946.png 2048w, \/blog\/wp-ttn-blog\/uploads\/2025\/07\/ObjectReferences-624x288.png 624w\" sizes=\"(max-width: 625px) 100vw, 625px\" \/><p id=\"caption-attachment-73661\" class=\"wp-caption-text\">Diagram illustrating how variables in stack memory reference objects stored in heap memory during Java program execution.<\/p><\/div>\n<p><strong>As shown in the example above:<\/strong><\/p>\n<ul>\n<li>Primitive integer value is stored in stack memory.<\/li>\n<li>The string literals &#8220;Mohit&#8221; and &#8220;Ramtari&#8221; are stored in the <strong>String Pool<\/strong>, a part of the method area used for storing string literals.<\/li>\n<li>A MemoryManagement object is created in the <strong>heap memory<\/strong> and is referenced by the memoryManagement variable in the stack.<\/li>\n<li>A User object is also created in the heap and is <strong>referenced<\/strong> by two variables: userObject from the main method and user2Object from the dummyMethod.<\/li>\n<li>Once the dummyMethod completes execution and its closing bracket is reached, its stack frame is removed in <strong>Last-In First-Out (LIFO)<\/strong> order. As a result, all local variables within that method, including user2Object, are discarded, and control returns to the calling method (main in this case).<\/li>\n<\/ul>\n<div id=\"attachment_73663\" style=\"width: 635px\" class=\"wp-caption alignnone\"><img aria-describedby=\"caption-attachment-73663\" decoding=\"async\" loading=\"lazy\" class=\"size-large wp-image-73663\" src=\"https:\/\/www.tothenew.com\/blog\/wp-ttn-blog\/uploads\/2025\/07\/ObjectReferences2-1024x474.png\" alt=\"Diagram showing Java memory after dummyMethod has completed. The stack frame for dummyMethod is removed, and its local variables are discarded.\" width=\"625\" height=\"289\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2025\/07\/ObjectReferences2-1024x474.png 1024w, \/blog\/wp-ttn-blog\/uploads\/2025\/07\/ObjectReferences2-300x139.png 300w, \/blog\/wp-ttn-blog\/uploads\/2025\/07\/ObjectReferences2-768x356.png 768w, \/blog\/wp-ttn-blog\/uploads\/2025\/07\/ObjectReferences2-1536x712.png 1536w, \/blog\/wp-ttn-blog\/uploads\/2025\/07\/ObjectReferences2-2048x949.png 2048w, \/blog\/wp-ttn-blog\/uploads\/2025\/07\/ObjectReferences2-624x289.png 624w\" sizes=\"(max-width: 625px) 100vw, 625px\" \/><p id=\"caption-attachment-73663\" class=\"wp-caption-text\">Diagram illustrating the state of memory after the execution of dummyMethod, showing the removal of its stack frame and how object references are affected.<\/p><\/div>\n<p>Once the dummyMethod completes execution, control returns to the main method. Since there is no further code to execute after the call to dummyMethod, the closing bracket of the main method is reached. As a result, its scope also ends, and the corresponding stack frame is removed following the <strong>Last-In-First-Out (LIFO)<\/strong> order.<\/p>\n<p>At this point, the stack memory is completely cleared, and all references stored in it are removed. The memory now looks like this:<\/p>\n<div id=\"attachment_73664\" style=\"width: 635px\" class=\"wp-caption alignnone\"><img aria-describedby=\"caption-attachment-73664\" decoding=\"async\" loading=\"lazy\" class=\"size-large wp-image-73664\" src=\"https:\/\/www.tothenew.com\/blog\/wp-ttn-blog\/uploads\/2025\/07\/EmptyStack-1024x588.png\" alt=\"Diagram illustrating Java memory after program execution is complete. Both dummyMethod and main method stack frames have been removed, leaving the stack memory empty. Heap memory still contains objects that were previously referenced, but now have no active references from the stack.\" width=\"625\" height=\"359\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2025\/07\/EmptyStack-1024x588.png 1024w, \/blog\/wp-ttn-blog\/uploads\/2025\/07\/EmptyStack-300x172.png 300w, \/blog\/wp-ttn-blog\/uploads\/2025\/07\/EmptyStack-768x441.png 768w, \/blog\/wp-ttn-blog\/uploads\/2025\/07\/EmptyStack-1536x882.png 1536w, \/blog\/wp-ttn-blog\/uploads\/2025\/07\/EmptyStack-2048x1175.png 2048w, \/blog\/wp-ttn-blog\/uploads\/2025\/07\/EmptyStack-624x358.png 624w\" sizes=\"(max-width: 625px) 100vw, 625px\" \/><p id=\"caption-attachment-73664\" class=\"wp-caption-text\">Diagram showing the final memory state after the execution of both dummyMethod and main method, with the stack cleared and only heap objects remaining.<\/p><\/div>\n<p>Now that the stack memory is cleared and all references have been removed, the objects in the heap memory <strong>remain without any active links<\/strong> pointing to them. This is the stage where the Garbage Collector (GC) steps in to manage unused objects. The Garbage Collector is responsible for automatically identifying and removing objects in the heap that are no longer referenced by any part of the program.<\/p>\n<p>The JVM determines when the Garbage Collector should run. When the GC runs, it reclaims memory by cleaning up all unreachable objects, helping to ensure efficient memory utilization and prevent memory leaks.<\/p>\n<h3>Divisions of Heap Memory :<\/h3>\n<p>The heap memory in Java is primarily divided into two main areas:<\/p>\n<ul>\n<li>Young Generation<\/li>\n<li>Old Generation (Tenured Generation)<\/li>\n<\/ul>\n<p>In addition to the heap, there is also a separate memory area known as <strong>Metaspace<\/strong>, which is considered non-heap memory. It holds information about classes, including their structure, defined methods, and runtime constants. (Note: Metaspace replaced PermGen starting from Java 8.)<\/p>\n<p><strong>Young Generation : <\/strong>Young Generation refers to the section of heap memory where objects are first allocated upon creation.<br \/>\nIt is further divided into:<\/p>\n<ol>\n<li>Eden Space &#8211; It is the region where the new objects are first allocated in memory.<\/li>\n<li>Survivor Space 0 (S0)<\/li>\n<li>Survivor Space 1 (S1)<\/li>\n<\/ol>\n<p>The two Survivor spaces (S0 and S1) work in a ping-pong fashion during garbage collection. During a <strong>Minor GC<\/strong>, objects that are still alive in the Eden space are moved to one of the Survivor spaces. Objects that survive multiple collections may eventually be <strong>promoted to the Old Generation<\/strong>.<\/p>\n<div id=\"attachment_73665\" style=\"width: 635px\" class=\"wp-caption alignnone\"><img aria-describedby=\"caption-attachment-73665\" decoding=\"async\" loading=\"lazy\" class=\"size-large wp-image-73665\" src=\"https:\/\/www.tothenew.com\/blog\/wp-ttn-blog\/uploads\/2025\/07\/MemoryBreakdown-1024x328.png\" alt=\"Diagram showing Java heap memory structure divided into Young Generation and Old Generation. The Young Generation includes Eden space and two Survivor spaces (S0 and S1). The image also highlights Metaspace as non-heap memory used for storing class metadata.\" width=\"625\" height=\"200\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2025\/07\/MemoryBreakdown-1024x328.png 1024w, \/blog\/wp-ttn-blog\/uploads\/2025\/07\/MemoryBreakdown-300x96.png 300w, \/blog\/wp-ttn-blog\/uploads\/2025\/07\/MemoryBreakdown-768x246.png 768w, \/blog\/wp-ttn-blog\/uploads\/2025\/07\/MemoryBreakdown-1536x492.png 1536w, \/blog\/wp-ttn-blog\/uploads\/2025\/07\/MemoryBreakdown-2048x656.png 2048w, \/blog\/wp-ttn-blog\/uploads\/2025\/07\/MemoryBreakdown-624x200.png 624w\" sizes=\"(max-width: 625px) 100vw, 625px\" \/><p id=\"caption-attachment-73665\" class=\"wp-caption-text\">Diagram illustrating the division of heap memory in Java, including Young Generation (Eden, Survivor 0, Survivor 1), Old Generation, and Metaspace (non-heap memory).<\/p><\/div>\n<p><strong>Let\u2019s explore how memory behaves when new objects are created.<\/strong><\/p>\n<p>Suppose we create five objects: <strong>O1, O2, O3, O4,<\/strong> and <strong>O5<\/strong>.<br \/>\nWhen these objects are instantiated, they are <strong>initially stored in the Eden space<\/strong> of the Young Generation within the heap memory.<\/p>\n<p>The Eden space is specifically designed to hold newly created (short-lived) objects. Most of these objects will become unreachable quickly and are candidates for garbage collection during the next minor GC cycle.<\/p>\n<div id=\"attachment_73666\" style=\"width: 635px\" class=\"wp-caption alignnone\"><img aria-describedby=\"caption-attachment-73666\" decoding=\"async\" loading=\"lazy\" class=\"wp-image-73666 size-large\" src=\"https:\/\/www.tothenew.com\/blog\/wp-ttn-blog\/uploads\/2025\/07\/ObjectsInMemory-1024x218.png\" alt=\"Diagram illustrating five newly created objects labeled O1, O2, O3, O4, and O5 placed in the Eden space of the Young Generation in Java heap memory. The Young Generation is shown as divided into Eden, Survivor 0 (S0), and Survivor 1 (S1).\" width=\"625\" height=\"133\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2025\/07\/ObjectsInMemory-1024x218.png 1024w, \/blog\/wp-ttn-blog\/uploads\/2025\/07\/ObjectsInMemory-300x64.png 300w, \/blog\/wp-ttn-blog\/uploads\/2025\/07\/ObjectsInMemory-768x163.png 768w, \/blog\/wp-ttn-blog\/uploads\/2025\/07\/ObjectsInMemory-1536x327.png 1536w, \/blog\/wp-ttn-blog\/uploads\/2025\/07\/ObjectsInMemory-2048x436.png 2048w, \/blog\/wp-ttn-blog\/uploads\/2025\/07\/ObjectsInMemory-624x133.png 624w\" sizes=\"(max-width: 625px) 100vw, 625px\" \/><p id=\"caption-attachment-73666\" class=\"wp-caption-text\">Diagram showing the allocation of five objects within the Eden region of the Young Generation in Java&#8217;s heap memory.<\/p><\/div>\n<p>Now, let\u2019s assume that objects<strong> O1<\/strong> and <strong>O2<\/strong> are no longer referenced by any variable. When the Garbage Collector (GC) runs, it applies the <strong>Mark and Sweep<\/strong> algorithm:<\/p>\n<p><strong>Mark Phase:<\/strong> The GC first scans the heap and marks all unreferenced objects, such as O1 and O2 in this case.<br \/>\n<strong>Sweep Phase:<\/strong> It then performs two actions:<\/p>\n<ul>\n<li>Removes the marked (unreachable) objects \u2014 O1 and O2 \u2014 from memory.<\/li>\n<li>Moves the surviving objects (O3, O4, and O5) to one of the Survivor spaces (either S0 or S1) and increments their age, which helps determine their eligibility for promotion to the Old Generation over time.<\/li>\n<li>After this GC cycle, the memory state changes accordingly:<\/li>\n<\/ul>\n<div id=\"attachment_73667\" style=\"width: 635px\" class=\"wp-caption alignnone\"><img aria-describedby=\"caption-attachment-73667\" decoding=\"async\" loading=\"lazy\" class=\"size-large wp-image-73667\" src=\"https:\/\/www.tothenew.com\/blog\/wp-ttn-blog\/uploads\/2025\/07\/AfterGC-1024x218.png\" alt=\"Diagram depicting the Java heap after a Garbage Collection cycle. Objects O1 and O2 are marked as unreferenced and removed from Eden. Objects O3, O4, and O5, still referenced, are moved to a Survivor space (S0 or S1), and their object age is incremented to track GC cycles.\" width=\"625\" height=\"133\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2025\/07\/AfterGC-1024x218.png 1024w, \/blog\/wp-ttn-blog\/uploads\/2025\/07\/AfterGC-300x64.png 300w, \/blog\/wp-ttn-blog\/uploads\/2025\/07\/AfterGC-768x163.png 768w, \/blog\/wp-ttn-blog\/uploads\/2025\/07\/AfterGC-1536x327.png 1536w, \/blog\/wp-ttn-blog\/uploads\/2025\/07\/AfterGC-2048x436.png 2048w, \/blog\/wp-ttn-blog\/uploads\/2025\/07\/AfterGC-624x133.png 624w\" sizes=\"(max-width: 625px) 100vw, 625px\" \/><p id=\"caption-attachment-73667\" class=\"wp-caption-text\">Diagram showing the effect of Garbage Collection using the Mark and Sweep algorithm. Unreferenced objects O1 and O2 are removed from Eden, while surviving objects O3, O4, and O5 are moved to a Survivor space with their age incremented.<\/p><\/div>\n<p><strong>Object Movement and Promotion to Old Generation<\/strong><br \/>\nOn subsequent runs of the Garbage Collector (GC), if any of the objects (O3, O4, or O5) become unreferenced, they will be removed from memory. If they are still referenced, they will be moved to the other Survivor space (e.g., from S0 to S1), and their age is incremented by 1.<\/p>\n<p>Objects continue moving back and forth between S0 and S1 across multiple GC cycles. This process continues until either:<\/p>\n<ol>\n<li>The object becomes unreferenced (and is collected), <strong>or<\/strong><\/li>\n<li>The object\u2019s age reaches a specified limit known as the <strong>tenuring threshold<\/strong>.<br \/>\nOnce the threshold is reached, and the object is still alive, it is promoted to the Old Generation \u2014 a section of the heap meant for long-lived objects.<\/li>\n<\/ol>\n<p><strong>Minor GC vs. Major GC<\/strong><\/p>\n<ul>\n<li>Minor GC takes place in the Young Generation and usually runs quickly and often, since most objects in this region have a short lifespan.<\/li>\n<li>Major GC (also called Full GC) occurs in the Old Generation, where long-lived objects reside. It is less frequent but more time-consuming, as it deals with a larger memory space and performs more thorough cleanup.<\/li>\n<\/ul>\n<h3>Conclusion<\/h3>\n<h3>Java\u2019s memory management efficiently handles object allocation and cleanup through stack and heap memory, along with automated garbage collection. Understanding how objects move through Eden, Survivor spaces, and into the Old Generation\u2014and the roles of Minor and Major GC\u2014helps developers write more optimized and reliable applications.<\/h3>\n<p>What\u2019s Next<\/p>\n<p><em>Stay tuned for Part 2, where we\u2019ll uncover how different garbage collectors work, when to use them, and how they manage memory over time.<\/em><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Introduction Java memory management refers to the process by which the Java Virtual Machine (JVM) allocates, organizes, and reclaims memory used by variables, methods, classes, and objects during program execution. It ensures efficient memory use by automatically managing object creation and destruction, helping developers avoid manual memory handling and common pitfalls like memory leaks. Types [&hellip;]<\/p>\n","protected":false},"author":1843,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"iawp_total_views":164},"categories":[446],"tags":[7697,7700,4781,4844,7698,7695,7694,7696,3836,7703,7701,7699,7702,5823],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/73668"}],"collection":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/users\/1843"}],"replies":[{"embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/comments?post=73668"}],"version-history":[{"count":5,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/73668\/revisions"}],"predecessor-version":[{"id":75884,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/73668\/revisions\/75884"}],"wp:attachment":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/media?parent=73668"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/categories?post=73668"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/tags?post=73668"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}