Stack vs Heap Memory in Java – Where Does Your Data Live? 🧠 Stack Memory: ▸ Method calls + local variables ▸ LIFO (Last In, First Out) ▸ Very fast, auto-cleared after method ends ▸ Each thread has its own stack Heap Memory: ▸ Stores objects & instance variables ▸ Shared across threads ▸ Managed by Garbage Collector ▸ Slower than Stack, can throw OutOfMemoryError Example: void demo() { int x = 10; String s = new String("Java"); } ▸ x → Stack ▸ s (reference) → Stack ▸ "Java" object → Heap Rule: → Primitives → Stack → References → Stack → Objects → Heap #Java #SpringBoot #BackendDevelopment #Memory #JavaDeveloper
Stack vs Heap Memory in Java Explained
More Relevant Posts
-
Stack vs Heap Memory in Java – Where Does Your Data Live? 🧠 Stack Memory: ▸ Method calls + local variables ▸ LIFO (Last In, First Out) ▸ Very fast, auto-cleared after method ends ▸ Each thread has its own stack Heap Memory: ▸ Stores objects & instance variables ▸ Shared across threads ▸ Managed by Garbage Collector ▸ Slower than Stack, can throw OutOfMemoryError Example: void demo() { int x = 10; String s = new String("Java"); } ▸ x → Stack ▸ s (reference) → Stack ▸ "Java" object → Heap Rule: → Primitives → Stack → References → Stack → Objects → Heap #Java #SpringBoot #BackendDevelopment #Memory #JavaDeveloper
To view or add a comment, sign in
-
-
🚀 Day 19 – map() vs flatMap() in Java Streams While working with Streams, I came across a subtle but important difference: "map()" vs "flatMap()". --- 👉 map() Transforms each element individually List<String> names = Arrays.asList("java", "spring"); names.stream() .map(String::toUpperCase) .forEach(System.out::println); ✔ Output: JAVA, SPRING --- 👉 flatMap() Flattens nested structures List<List<Integer>> list = Arrays.asList( Arrays.asList(1, 2), Arrays.asList(3, 4) ); list.stream() .flatMap(Collection::stream) .forEach(System.out::println); ✔ Output: 1, 2, 3, 4 --- 💡 Key insight: - "map()" → 1-to-1 transformation - "flatMap()" → 1-to-many (and then flatten) --- ⚠️ Real-world use: "flatMap()" is very useful when dealing with: - Nested collections - API responses - Complex data transformations --- 💡 Takeaway: Understanding when to use "flatMap()" can make your stream operations much cleaner and more powerful. #Java #BackendDevelopment #Java8 #Streams #LearningInPublic
To view or add a comment, sign in
-
Java Arrays: The Ultimate Building Blocks Before building complex data structures, the foundation needs to be rock solid. Arrays are the ultimate building blocks. Today, I locked down the 4 core operations: 1. Declare: Reserving contiguous memory. 2. Initialize: Populating the data. 3. Access: The magic of O(1). 4. Traverse: Looping through the elements. The biggest takeaway? Understanding fixed memory allocation in Java is crucial before moving to dynamic structures like ArrayLists or HashMaps. #DSA #Java #ArrayBasics
To view or add a comment, sign in
-
-
#Post6 In the previous post, we understood how our code runs: Code → JVM → Process → Threads (https://lnkd.in/dns348v6) Now let’s go one step deeper What actually happens inside a process when it executes? When a Java program runs, the JVM creates a process. Inside that process, memory and execution are organized into different parts. 1. Heap Memory (Shared) This is where objects created using the "new" keyword are stored. • Shared by all threads within the same process • Not shared across different processes • Threads can read and modify data Because multiple threads access it → synchronization is required 2. Code Segment (Shared) Contains the bytecode (instructions to execute). • Read-only • Shared across all threads 3. Data Segment (Shared) Stores static and global variables. • Shared across all threads • Can be modified Synchronization is required when multiple threads update data 4. Stack (Thread-specific) Each thread has its own stack. • Stores method calls • Stores local variables • Not shared between threads 5. Program Counter (Thread-specific) Each thread has its own program counter. • Points to the current instruction being executed • Moves forward as execution progresses 6. Registers (Thread-specific) Each thread uses CPU registers to store temporary/intermediate data during execution. (We will explore how registers are used during context switching in upcoming posts) Important Understanding Inside a process: • Heap + Code + Data → Shared across threads • Stack + Program Counter + Registers → Private to each thread This separation is what makes multithreading both powerful and complex. Key takeaway Threads share memory (heap), but execute independently using their own stack and execution state. In the next post, we’ll explore Registers and how CPU switches between threads (context switching). #Java #SoftwareEngineering #Multithreading #BackendDevelopment #Programming
To view or add a comment, sign in
-
If your class name looks like CoffeeWithMilkAndSugarAndCream… you’ve already lost. This is how most codebases slowly break: You start with one clean class. Then come “small changes”: add logging add validation add caching So you create: a few subclasses… then a few more or pile everything into if-else Now every change touches existing code. And every change risks breaking something. That’s not scaling. That’s slow decay. The Decorator Pattern fixes this in a simple way: Don’t modify the original class. Wrap it. Start with a base object → then layer behavior on top of it. Each decorator: adds one responsibility doesn’t break existing code can be combined at runtime No subclass explosion. No god classes. No fragile code. Real-world example? Java I/O does this everywhere: you wrap streams on top of streams. The real shift is this: Stop thinking inheritance. Start thinking composition. Because most “just one more feature” problems… are actually design problems. Have you ever seen a codebase collapse under too many subclasses or flags? #DesignPatterns #LowLevelDesign #SystemDesign #CleanCode #Java #SoftwareEngineering #OOP Attaching the decorator pattern diagram with a simple example.
To view or add a comment, sign in
-
-
#Post4 In the previous post, we understood how request mapping works using @GetMapping and others. Now the next question is 👇 How does Spring Boot handle data sent from the client? That’s where @RequestBody comes in 🔥 When a client sends JSON data → it needs to be converted into a Java object. Example request (JSON): { "name": "User", "age": 25 } Controller: @PostMapping("/user") public User addUser(@RequestBody User user) { return user; } 👉 Spring automatically converts JSON → Java object This is done using a library called Jackson (internally) 💡 Why is this useful? • No manual parsing needed • Clean and readable code Key takeaway: @RequestBody makes it easy to handle request data in APIs 🚀 In the next post, we will understand @PathVariable and @RequestParam 🔥 #Java #SpringBoot #BackendDevelopment #RESTAPI #LearnInPublic
To view or add a comment, sign in
-
𝗧𝗵𝗲 𝗝𝗮𝘃𝗮 𝘀𝘄𝗶𝘁𝗰𝗵 𝘀𝘁𝗮𝘁𝗲𝗺𝗲𝗻𝘁 𝘁𝘂𝗿𝗻𝗲𝗱 𝟯𝟬 𝘁𝗵𝗶𝘀 𝘆𝗲𝗮𝗿 Here's the short version: What started as a C-style branching construct is now a declarative data-matching engine — and the JVM internals behind it are genuinely fascinating. What I learned going deep on this: → Early switch relied on jump tables — fast, but fall-through bugs were silent and destructive → Java added definite assignment rules, preventing uninitialized variables from slipping through → The JVM picks between tableswitch (O(1)) and lookupswitch (O(log n)) based on how dense your cases are → String switching since Java 7 uses hashCode + equals internally — it's not magic, it's two passes → Java 14 made switch an expression, which killed fall-through at the language level → Modern Java (21+) adds pattern matching with type binding and null handling — code reads like a description of data → invokedynamic enables runtime linking, replacing rigid compile-time dispatch tables → Java 25 enforces unconditional exactness in type matching — no more silent data loss • The real shift isn't syntax. It's the question switch answers. Old: "Where should execution go?" New: "What is the shape of this data?" That's not just a feature upgrade. That's a change in how you think about branching. Which of these surprised you most? Drop it in the comments. A special thanks to Syed Zabi Ulla sir at PW Institute of Innovation for their clear explanations and continuous guidance throughout this topic. #Java #Programming #SoftwareEngineering #JVM #LearningInPublic #CodingJourney
To view or add a comment, sign in
-
Stop wasting memory on threads that do nothing. 🛑 If you’re building Java backends, you’ve probably seen this: More users → more threads → more RAM usage I recently explored Virtual Threads (Java 21 / Project Loom), and this concept finally clicked for me. 💡 The Problem In standard Java: 1 request = 1 Platform Thread During DB/API call → thread gets blocked It’s like a waiter standing idle while food is cooking 🍽️ 👉 Wasted resources + poor scalability 🔍 The Solution: Virtual Threads 👉 Lightweight threads managed by JVM (not OS) Cheap to create Can run thousands easily Perfect for I/O-heavy backend systems ⚙️ How it actually works (Mounting / Unmounting) 1️⃣ Mounting Virtual Thread runs on a Carrier Thread (Platform Thread) 2️⃣ I/O Call (DB/API) Your code looks blocking 3️⃣ Unmounting (Parking) Virtual Thread is paused & parked in heap memory 👉 It releases the Carrier Thread 4️⃣ Carrier Thread is free Handles another request immediately 5️⃣ Remounting (Resume) Once response comes → Virtual Thread continues 💻 The "magic" in code // Looks like blocking code Runnable task = () -> { System.out.println("Processing: " + Thread.currentThread()); String data = fetchDataFromDB(); // DB/API call System.out.println("Result: " + data); }; // Run using Virtual Thread Thread.ofVirtual().start(task); 🧩 What’s happening behind the scenes? 👉 Thread.ofVirtual() Creates a lightweight thread (stored in heap, not OS-level) 👉 During DB/API call Virtual Thread gets unmounted (parked) Carrier Thread becomes free 👉 While waiting Same thread handles other requests 👉 When response comes Scheduler remounts Virtual Thread Execution continues 📈 Result No idle threads Better resource usage Simple synchronous code High scalability without complex async code 🧠 Biggest takeaway 👉 “Code looks blocking… but system is not blocked.” That’s the mindset shift. Have you tried Virtual Threads in your services yet? Did you see any real performance improvement? 🤔 #Java #BackendEngineering #VirtualThreads #ProjectLoom #Java21 #Microservices #Performance
To view or add a comment, sign in
-
-
You can brute force this in O(n²)… or think smart and finish in O(n). Day 71 — LeetCode Progress Problem: Number of Good Pairs Required: Given an array nums, return the number of pairs (i, j) such that: i < j nums[i] == nums[j] Idea: Instead of checking all pairs, count frequency of each number. If a number appears c times, it can form: c × (c - 1) / 2 pairs. Approach: Use a HashMap to store frequency of each number Traverse the array and build frequency map For each frequency c: Add c * (c - 1) / 2 to result Return the result Time Complexity: O(n) Space Complexity: O(n) Small problem, but a powerful pattern: Counting + combinations = huge optimization. #LeetCode #DSA #Java #HashMap #ProblemSolving #CodingJourney” Day 71 — LeetCode Progress Problem: Number of Good Pairs Required: Given an array nums, return the number of pairs (i, j) such that: i < j nums[i] == nums[j] Idea: Instead of checking all pairs, count frequency of each number. If a number appears c times, it can form: c × (c - 1) / 2 pairs. Approach: Use a HashMap to store frequency of each number Traverse the array and build frequency map For each frequency c: Add c * (c - 1) / 2 to result Return the result Time Complexity: O(n) Space Complexity: O(n) Small problem, but a powerful pattern: Counting + combinations = huge optimization. #LeetCode #DSA #Java #HashMap #ProblemSolving #CodingJourney
To view or add a comment, sign in
-
-
Most Java performance issues don’t show up in code reviews They show up in object lifetimes. Two pieces of code can look identical: same logic same complexity same output But behave completely differently in production. Why? Because of how long objects live. Example patterns: creating objects inside tight loops → short-lived → frequent GC holding references longer than needed → objects move to old gen caching “just in case” → memory pressure builds silently Nothing looks wrong in the code. But at runtime: GC frequency increases pause times grow latency becomes unpredictable And the worst part? 👉 It doesn’t fail immediately. 👉 It degrades slowly. This is why some systems: pass load tests work fine initially then become unstable weeks later Takeaway: In Java, performance isn’t just about what you do. It’s about how long your data stays alive while doing it. #Java #JVM #Performance #Backend #SoftwareEngineering
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
Why Heap is slower? It’s not just GC. Heap objects are accessed via references and are scattered across memory, so the CPU can’t cache them efficiently. Unlike Stack (which is contiguous and thread-local), this causes more cache misses → slower access.