🛑 A Quick Java Memory Guide Understanding the Java Memory Model is non-negotiable for writing performant, bug-free code. If you don’t know where your data lives, you don’t really know Java. Here is the breakdown of Stack vs Heap: 🧠 The Stack (LIFO - Last In, First Out) · What lives here: Primitive values (int, double) and references to objects (pointers). · Scope: Each thread has its own private stack. Variables exist only as long as their method is running. · Access Speed: Very fast. · Management: Automatically freed when methods finish. 🗄️ The Heap (The Common Storage) · What lives here: The actual objects themselves (all instances of classes). · Scope: Shared across the entire application. · Access Speed: Slower than the stack due to global access. · Management: Managed by the Garbage Collector (GC). 💡 The Golden Rule: The reference is on the Stack, but the object it points to is on the Heap. Map<String, String> myMap = new HashMap<>(); (Stack: myMap) --> (Heap: HashMap object) 👇 Q1: If I declare int id = 5; inside a method, where is this value stored? A1: Stack. It's a local primitive variable, so it lives directly in the stack frame. Q2: I created an array: int[] data = new int[100];. The array holds primitives. Is the data stored on the Stack or Heap? A2: Heap. The array itself is an object in Java. The reference data lives on the Stack, but the 100 integers are stored contiguously on the Heap. Q3: What happens to memory if I pass this object reference to another method? A3: A copy of the reference is passed (passed by value). Both methods now have a pointer (on their respective stacks) to the same single object on the Heap. ♻️ Repost if you found this helpful! Follow me for more Java wisdom. #Java #Programming #SoftwareEngineering #MemoryManagement #Coding
Java Memory Model: Stack vs Heap
More Relevant Posts
-
Day 21 – Accessing Non-Static Members of a Class in Java Yesterday I explored static members in Java. Today’s concept was the opposite side of it: 👉 Non-Static Members (Instance Members) Unlike static members, non-static members belong to objects, not the class itself. That means we must create an object of the class to access them. 🔹 Syntax new ClassName().memberName; or ClassName obj = new ClassName(); obj.memberName; 🔹 Example class Demo4 { int x = 100; int y = 200; void test() { System.out.println("running test() method"); } } class MainClass2 { public static void main(String[] args) { System.out.println("x = " + new Demo4().x); System.out.println("y = " + new Demo4().y); new Demo4().test(); } } Output x = 100 y = 200 running test() method 🔹 Important Observation Every time we write: new Demo4() ➡️ A new object is created. Each object has its own copy of non-static variables. This is why instance variables are object-specific, unlike static variables which are shared across objects. 📌 Key takeaway • Static members → belong to the class • Non-static members → belong to objects • Accessing instance members requires object creation Understanding this concept is essential for mastering Object-Oriented Programming in Java. Step by step building stronger Core Java fundamentals. #Java #CoreJava #JavaFullStack #OOP #Programming #BackendDevelopment #LearningInPublic #SoftwareDevelopment
To view or add a comment, sign in
-
-
Java records are powerful. But they are not a replacement for every POJO. That is where many teams get the migration decision wrong. A record is best when your type is mainly a transparent carrier for a fixed set of values. Java gives you the constructor, accessors, equals(), hashCode(), and toString() automatically, which makes records great for DTOs, request/response models, and small value objects. But records also come with important limits. A record is shallowly immutable, its components are fixed in the header, it cannot extend another class because it already extends java.lang.Record, and you cannot add extra instance fields outside the declared components. You can still add validation in a canonical or compact constructor, but records are a poor fit when the model needs mutable state, framework-style setters, or inheritance-heavy design. So the real question is not: “Should we convert all POJOs to records?” The better question is: “Which POJOs are actually just data carriers?” That is where records shine. A practical rule: use records for immutable data transfer shapes, keep normal classes for JPA entities, mutable domain objects, lifecycle-heavy models, and cases where behavior and state evolve over time. Also, one important clarification: this is not really a “Java 25 only” story. Records became a permanent Java feature in Java 16, and Java 25 documents them as part of the standard language model. So no, the answer is not “change every POJO to record.” Change only the POJOs that truly represent fixed data. Where do you draw the line in your codebase: DTOs only, or value objects too? #Java #Java25 #JavaRecords #SoftwareEngineering #BackendDevelopment #CleanCode #JavaDeveloper #Programming #SystemDesign #TechLeadership
To view or add a comment, sign in
-
-
🔍 Deep Dive: Internals of HashMap in Java HashMap is one of the most widely used data structures in Java, but have you ever wondered how it works under the hood? Let’s break it down. 🧩 Core Structure - Internally, a HashMap is backed by an array of buckets. - Each bucket stores entries as Nodes (key, value, hash, next). - Before Java 8: collisions were handled using linked lists. - From Java 8 onwards: if collisions in a bucket exceed a threshold (default 8), the list is converted into a balanced Red-Black Tree for faster lookups. ⚙️ Hashing & Indexing - When you insert a key-value pair, the hashCode() of the key is computed. - This ensures uniform distribution of keys across buckets. 🚀 Performance - Average time complexity for put() and get() is O(1), assuming a good hash function. - Worst case (all keys collide into one bucket): - Before Java 8 → O(n) due to linked list traversal. - After Java 8 → O(log n) thanks to tree-based buckets. 🛠️ Key Design Choices - Load Factor (default 0.75): controls when the HashMap resizes. - Rehashing: when capacity × load factor is exceeded, the array doubles in size and entries are redistributed. - Null Handling: HashMap allows one null key and multiple null values. 💡 Takeaway HashMap is a brilliant example of balancing speed, memory efficiency, and collision handling. Its evolution from linked lists to trees highlights how Java adapts to real-world performance needs. What’s your favorite use case of HashMap in production systems? #Java #Collections #ScalableSystems
To view or add a comment, sign in
-
Java Heap Dumps might contain sensitive information; with hprof-redact, you can easily remove it. Learn more in this blog post: https://lnkd.in/dn5CUtst
To view or add a comment, sign in
-
Have you ever thought about how Java stores the classes, methods, and variables you write? What happens inside the JVM after you run your Java program? In the Medium blog post below, I have discussed how the JVM manages all of these. If you found this helpful, please give it a like and follow me to stay tuned for my next blog on Garbage Collection.
To view or add a comment, sign in
-
A few fundamental Java concepts continue to have a significant impact on system design, performance, and reliability — especially in backend applications operating at scale. Here are three that are often used daily, but not always fully understood: 🔵 HashMap Internals At a high level, HashMap provides O(1) average time complexity, but that performance depends heavily on how hashing and collisions are managed internally. Bucket indexing is driven by hashCode() Collisions are handled via chaining, and in Java 8+, transformed into balanced trees under high contention Resizing and rehashing can introduce performance overhead if not considered carefully 👉 In high-throughput systems, poor key design or uneven hash distribution can quickly degrade performance. 🔵 equals() and hashCode() Contract These two methods directly influence the correctness of hash-based collections. hashCode() determines where the object is stored equals() determines how objects are matched within that location 👉 Any inconsistency between them can lead to subtle data retrieval issues that are difficult to debug in production environments. 🔵 String Immutability String immutability is a deliberate design choice in Java that enables: Safe usage in multi-threaded environments Efficient memory utilization through the String Pool Predictable behavior in security-sensitive operations 👉 For scenarios involving frequent modifications, relying on immutable Strings can introduce unnecessary overhead — making alternatives like StringBuilder more appropriate. 🧠 Engineering Perspective These are not just language features — they influence: Data structure efficiency Memory management Concurrency behavior Overall system scalability A deeper understanding of these fundamentals helps in making better design decisions, especially when building systems that need to perform reliably under load. #Java #BackendEngineering #SystemDesign #SoftwareArchitecture #Performance #Engineering
To view or add a comment, sign in
-
You can't instantiate an abstract class. Everyone knows that. But there are two ways to work with one — and knowing the difference makes you a better Java developer. 🔁 Part 2: How to "instantiate" an abstract class ✅ Option 1: Concrete Subclass (the standard way) Create a class that extends it and implements all abstract methods. abstract class Animal { abstract void speak(); } class Dog extends Animal { void speak() { System.out.println("Woof"); } } Animal a = new Dog(); // polymorphism ✅ This is the most common pattern. It's what Spring does under the hood with AbstractController, and what JUnit does with TestCase. ✅ Option 2: Anonymous Class (the quick way) No need to create a separate class. Java lets you implement it inline, on the spot. Animal a = new Animal() { void speak() { System.out.println("..."); } }; // ✅ Technically, Java creates an unnamed subclass behind the scenes. Useful for: one-off implementations, quick testing, callbacks. ⚡ Anonymous Class vs Lambda — what changed in Java 8? Before Java 8: anonymous classes were the go-to for passing behavior. After Java 8: if the abstract class has only ONE abstract method (functional interface), a lambda is cleaner. // Anonymous class (verbose) Runnable r = new Runnable() { public void run() { System.out.println("Running"); } }; // Lambda (clean) Runnable r = () -> System.out.println("Running"); Rule of thumb: → One abstract method + no shared state = use a lambda or functional interface → Multiple abstract methods + shared state = use abstract class + subclass 🎯 Real-world usage: Spring: AbstractController, AbstractMessageConverter JUnit: TestCase uses Template Method — setUp() and tearDown() are hooks you override Java Collections: AbstractList, AbstractMap give you most of the implementation for free The key insight: abstract classes aren't just restrictions. They're extension points — carefully designed places where the framework says "you decide what happens here." 📊 Oracle Java Docs — Anonymous Classes: https://lnkd.in/eVdJts4v 📊 Effective Java, Item 42 — Prefer lambdas to anonymous classes: https://lnkd.in/exH-cA-j #Java #OOP #SpringBoot #CleanCode #BackendDevelopment #SoftwareEngineering #TechLeadership
To view or add a comment, sign in
-
🚀 LazyConstants in Java JEP 526 brings constants which can be lazily initialized aka Lazy Constants. The concept was in first preview as Stable Values in JDK 25, it has been renamed to Lazy Constants and is in second preview. Lazy constants are treated as true constants by the JVM, which gives us the same immutability benefits as final fields, along with deferred initialization. ✅ Designed for objects which hold immutable data ✅ JVM treats stable values as constants, and you can get similar performance gains as final fields. ✅ Although similar to final fields, they are more flexible when it comes to the timing of initialization. ❓ How do they differ from final fields? ✔️ final fields are primarily used for managing immutability. However, final fields must be set eagerly, either during object construction for instance fields, or class initialization for static fields. ✔️ Even in cases where they are not used, all the final fields will get initialized eagerly. ✔️ Lazy Constants brings “deferred immutability” to us. ❓ How to create Lazy Constants? ✔️ A lazy constant is created using the factory method LazyConstant.of(Supplier) ✔️ When created, the lazy constant is not initialized, which means the constant is not yet set. ✔️The first time get() is called, the supplier function is executed and the constant value is set. ❓What if multiple threads try to initialize a lazy constant at the same time? ✔️A lazy constant is guaranteed to be initialized atomically and at most once. ✔️Only one updating thread can run the supplier function, and the other threads are blocked until the constant is initialized. #JavaByte #JavaTip #Java #JDK26 PS: This post is 100% human generated :)
To view or add a comment, sign in
-
-
#Post1 Internal working of HashMap And Hash collision 👇 When we insert a value: map.put("Apple", 10) Java performs these steps: 1️⃣ It calls hashCode() on the key. For example, Strings generate hash codes using a formula involving the prime number 31. 2️⃣ Using this hash, Java calculates the bucket index inside the internal array. Now the entry is stored inside that bucket. Example internal structure: Bucket Array [0] [1] [2] → (Apple,10) [3] [4] But what if two keys map to the same bucket? This situation is called a hash collision. Example: [2] → (Apple,10) → (Banana,20) → (Mango,30) HashMap handles collisions by storing multiple entries inside the same bucket. Before Java 8 • Entries were stored in a Linked List After Java 8 • If the bucket size grows beyond 8, the linked list is converted into a Red-Black Tree This improves search performance: O(n) → O(log n) Now let’s see what happens during get() when a bucket has multiple entries. When we call: map.get("Apple") Java performs these steps: 1️⃣ It recomputes the hashCode() of the key 2️⃣ It finds the same bucket index using (capacity - 1) & hash 3️⃣ If multiple nodes exist in that bucket, Java traverses the nodes For each node it checks: existingNode.hash == hash AND existingNode.key.equals(key) Once the correct key is found, the corresponding value is returned. Summary: Two different keys can generate the same hash, which causes a hash collision. HashMap handles collisions by storing entries as a Linked List or Red-Black Tree inside the bucket. 📌 Note HashMap is not thread safe. In the upcoming post, we will explore the thread-safe alternative to HashMap. #Java #SoftwareEngineering #BackendDevelopment #DataStructures #Programming #LearnInPublic
To view or add a comment, sign in
-
🚀 Day 30 and 31 – Deep Dive into Static in Java Over the last two days, I gained a strong understanding of the Static concept in Java from both execution and real-world perspectives. 1️⃣ How Java Program Executes (Memory Understanding) I understood how a Java program runs inside JRE memory, which includes: 1.Code Segment 2.Stack 3.Heap 4.Method Area (Static Segment / Meta space) 2️⃣ Execution Order in Java 1.Static variables 2.Static block 3.main() method 4.Object creation 5.Instance block 6.Constructor 7.Instance methods This clearly explains the difference between class-level loading and object-level creation. 3️⃣ Static vs Instance – Core Difference 🔹 Static Belongs to Class Memory allocated once Loaded during class loading Shared among all objects 🔹 Instance Belongs to Object Memory allocated per object Loaded during object creation Separate copy for each object 4️⃣ 💡 Real-Time Use Case of Static (Banking Example) Using a loan interest calculation example: If 10000 objects are created Instance variable creates 10000 copies in memory Static variable creates only 1 shared copy ✅ This improves memory efficiency and application performance. 5️⃣ 🔧 Static Members and Their Use Cases 🔹 Static Variable Used when value must be common for all objects Example: rate of interest, PI value, shared counters 🔹 Static Block Executes once during class loading Used to initialize static variables 🔹 Static Method Can be called without creating an object Used for utility/helper methods Example: Math class methods 6️⃣ 📌 Key Takeaways Static improves memory optimization Static belongs to class, not object Static variables load only once Static block runs once during class loading Static methods do not require object creation Execution flow understanding is important before learning Inheritance Feeling more confident about how Java works internally in memory 💻✨ Grateful to my trainer Sharath R for explaining the concept clearly and practically 🙌 #Java #CoreJava #OOPS #StaticKeyword #LearningJourney #BackendDevelopment #SoftwareEngineering #FullStackDeveloper
To view or add a comment, sign in
-
Explore content categories
- Career
- Productivity
- Finance
- Soft Skills & Emotional Intelligence
- Project Management
- Education
- Technology
- Leadership
- Ecommerce
- User Experience
- Recruitment & HR
- Customer Experience
- Real Estate
- Marketing
- Sales
- Retail & Merchandising
- Science
- Supply Chain Management
- Future Of Work
- Consulting
- Writing
- Economics
- Artificial Intelligence
- Employee Experience
- Workplace Trends
- Fundraising
- Networking
- Corporate Social Responsibility
- Negotiation
- Communication
- Engineering
- Hospitality & Tourism
- Business Strategy
- Change Management
- Organizational Culture
- Design
- Innovation
- Event Planning
- Training & Development