Skip to content
Rashmika_Harshamal edited this page Jul 20, 2026 · 6 revisions

Java Stack Memory

Introduction

Stack memory is used when Java methods are called.

Each thread has its own stack.

The stack stores:

  • Method calls
  • Local variables
  • Method parameters
  • Primitive local values
  • References to objects stored in heap memory

Stack memory is temporary.

When a method finishes, its stack frame is removed automatically.


Stack Frame

Every method call creates a new stack frame.

Example:

public void calculateTotal() {
    int quantity = 2;
    double price = 150.00;
    double total = quantity * price;
}

When calculateTotal() runs, a stack frame is created.

The stack frame contains:

quantity = 2
price = 150.00
total = 300.00

When the method finishes, the stack frame is removed.


Method Calls in Stack Memory

Example:

public void processBill() {
    calculateTotal();
}

public void calculateTotal() {
    double total = 500.00;
}

Stack order:

processBill()
    calculateTotal()

The most recently called method is removed first.

This is called:

Last In, First Out

or:

LIFO

Local Variables

Local variables are normally stored inside the current method's stack frame.

Example:

public void processPatient() {
    int patientCount = 10;
    boolean active = true;
}

The variables patientCount and active exist only while processPatient() is running.

They cannot be used after the method finishes.


Object References in Stack Memory

A local reference variable is stored in stack memory.

The actual object is stored in heap memory.

Example:

public void createPatient() {
    Patient patient = new Patient();
}

Memory idea:

Stack:
patient reference
        |
        v
Heap:
Patient object

The variable patient is in the stack frame.

The Patient object created with new Patient() is in heap memory.


Method Parameters

Method parameters are stored in the method's stack frame.

Example:

public double calculateNetTotal(
        double total,
        double discount) {

    return total - discount;
}

The parameters total and discount are available only while the method is running.


Primitive Values in Stack Memory

Primitive local variables are stored directly in the stack frame.

Example:

public void calculate() {
    int quantity = 5;
    double price = 200.00;
    boolean valid = true;
}

The values are stored directly:

quantity = 5
price = 200.00
valid = true

Stack Memory Example

public void processReport() {
    int recordCount = 20;
    String reportName = "Patient Report";
    Department department = new Department();
}

Memory idea:

Stack:
recordCount = 20
reportName reference
department reference

Heap:
"Patient Report" object
Department object

The local primitive recordCount is stored in the stack.

The local variables reportName and department store references.

Their objects are stored in heap memory.


Stack Overflow Error

Stack memory is limited.

A StackOverflowError may occur when methods call themselves continuously.

Example:

public void repeat() {
    repeat();
}

This method never stops calling itself.

Each call creates a new stack frame.

Eventually, the stack becomes full.

Result:

java.lang.StackOverflowError

Correct recursion must have a stopping condition.

public void countDown(int number) {
    if (number <= 0) {
        return;
    }

    countDown(number - 1);
}

Stack Memory and Threads

Each thread has its own stack.

Example:

Thread 1 → Stack 1
Thread 2 → Stack 2
Thread 3 → Stack 3

Local variables in one thread's stack are not directly shared with another thread.

However, stack references may point to the same object in heap memory.


Static and Non-Static Difference

Static Members

A static member belongs to the class.

Example:

private static int patientCount;

There is only one shared patientCount value for the class.

A static variable is not a local stack variable.

It is associated with the loaded class and is shared by all objects.

A static method can be called without creating an object.

public static boolean isValidAmount(double amount) {
    return amount > 0;
}

Call:

AmountValidator.isValidAmount(100.00);

When the static method runs, its local variables and parameters are still stored in a stack frame.

Example:

public static boolean isValidAmount(double amount) {
    boolean valid = amount > 0;
    return valid;
}

Here:

  • amount is in the method stack frame.
  • valid is in the method stack frame.
  • The method is static, but its local execution data still uses stack memory.

Non-Static Members

A non-static member belongs to an object.

Example:

private String patientName;

Each object has its own patientName value.

Patient firstPatient = new Patient();
Patient secondPatient = new Patient();

The two objects can store different names.

Non-static attributes are stored as part of their objects in heap memory.

When a non-static method runs, its local variables and parameters use stack memory.

Example:

public String formatPatientName() {
    String formattedName = patientName.trim();
    return formattedName;
}

Here:

  • patientName belongs to the object in heap memory.
  • formattedName is a local variable in stack memory.
  • The current object reference, called this, is available in the stack frame.

Static vs Non-Static Summary

Feature Static Non-static
Belongs to Class Object
Number of copies One shared copy One copy per object
Object required No Yes
Can access instance fields directly No Yes
Local variables during method call Stack Stack
Attribute storage Shared class-associated storage Inside object in heap

HMIS-Style Example

public class PatientReport {

    private static int generatedReportCount;

    private String reportName;
    private Department department;

    public void generateReport() {
        int resultCount = 25;

        generatedReportCount++;

        System.out.println(reportName);
        System.out.println(resultCount);
    }

    public static int getGeneratedReportCount() {
        return generatedReportCount;
    }
}

Memory idea:

Stack during generateReport():
resultCount = 25
this reference

Heap:
PatientReport object
reportName
department

Shared static data:
generatedReportCount

Important Points

  1. Each thread has its own stack.
  2. Every method call creates a stack frame.
  3. Local variables are stored in the stack frame.
  4. Method parameters are stored in the stack frame.
  5. Local object variables store references in the stack.
  6. Actual objects are stored in heap memory.
  7. Stack data is removed when the method finishes.
  8. Static methods still use stack frames when they execute.
  9. Non-static attributes belong to objects in heap memory.
  10. Infinite recursion can cause StackOverflowError.

Summary

Stack memory is mainly used for method execution.

It stores:

Method calls
Local variables
Parameters
Primitive local values
Object references

Example:

public void process() {
    int count = 10;
    Patient patient = new Patient();
}

Memory idea:

Stack:
count = 10
patient reference

Heap:
Patient object

Java Heap Memory

Introduction

Heap memory is used to store Java objects and arrays.

Objects created using the new keyword are normally stored in heap memory.

Example:

Patient patient = new Patient();

The Patient object is stored in heap memory.

The local reference variable patient is stored in the current method's stack frame.


What Is Stored in Heap Memory?

Heap memory stores:

  • Objects
  • Object attributes
  • Arrays
  • Collections
  • String objects
  • Non-static attributes
  • Shared objects referenced by different methods or threads

Example:

Patient patient = new Patient();
Department department = new Department();
List<Bill> bills = new ArrayList<>();

The following objects are stored in heap memory:

Patient object
Department object
ArrayList object
Bill objects added to the list

Objects in Heap Memory

Example:

Patient patient = new Patient();

Memory idea:

Stack:
patient reference
        |
        v
Heap:
Patient object

The reference variable points to the object.


Non-Static Attributes in Heap Memory

Non-static attributes belong to an object.

Example:

public class Patient {

    private String patientCode;
    private String patientName;
    private boolean retired;
}

When a Patient object is created:

Patient patient = new Patient();

The object and its non-static attributes are stored in heap memory.

Memory idea:

Heap:
Patient object
    patientCode
    patientName
    retired

Each object has its own values.

Patient firstPatient = new Patient();
Patient secondPatient = new Patient();

Memory idea:

Heap:
Patient object 1
Patient object 2

The two objects can store different patient details.


Arrays in Heap Memory

Arrays are objects and are stored in heap memory.

Example:

int[] patientCounts = new int[5];

Memory idea:

Stack:
patientCounts reference
        |
        v
Heap:
int array with 5 elements

Object array:

Patient[] patients = new Patient[3];

The array object is stored in heap memory.

The array initially contains three null references.


Collections in Heap Memory

Collection objects are stored in heap memory.

Example:

List<Patient> patients = new ArrayList<>();

Memory idea:

Stack:
patients reference
        |
        v
Heap:
ArrayList object

When patient objects are added:

patients.add(new Patient());

Both the ArrayList and the Patient object are in heap memory.


Strings in Heap Memory

Strings are objects.

Example:

String patientName = "Kamal";

The reference variable may be local to a method and stored in stack memory.

The string object is stored in heap memory.

String literals may be stored in the Java String Pool, which is part of heap memory.


Garbage Collection

Java automatically manages heap memory using garbage collection.

An object becomes eligible for garbage collection when no reachable reference points to it.

Example:

Patient patient = new Patient();
patient = null;

After patient becomes null, the object may become eligible for garbage collection if no other reference points to it.

Garbage collection:

  • Finds unreachable objects
  • Releases heap memory
  • Runs automatically
  • Does not run at an exact time chosen by the programmer

Heap Memory Error

Heap memory is limited.

If the application creates too many objects and memory cannot be released, Java may throw:

java.lang.OutOfMemoryError: Java heap space

Example problem:

List<Patient> patients = new ArrayList<>();

while (true) {
    patients.add(new Patient());
}

The list keeps references to every object.

Garbage collection cannot remove them because they are still reachable.


Memory Leak

A memory leak happens when objects are no longer needed but are still referenced.

Example:

private static final List<Patient> patients =
        new ArrayList<>();

If the application continuously adds patients and never removes them:

patients.add(patient);

the list can grow for the entire application lifetime.

This is especially dangerous because it is static and shared.

HMIS applications should not keep patient records in unnecessary long-lived static collections.


Static and Non-Static Difference

Static Attributes

A static attribute belongs to the class.

Example:

private static int generatedReportCount;

There is only one shared value for the class.

All objects use the same static value.

PatientReport firstReport = new PatientReport();
PatientReport secondReport = new PatientReport();

Both objects share:

generatedReportCount

A static reference can point to an object in heap memory.

Example:

private static List<String> reportNames =
        new ArrayList<>();

The ArrayList object is in heap memory.

The static field keeps a shared reference to that object.

Because the static field may live as long as the class remains loaded, the object may also remain reachable for a long time.

Non-Static Attributes

A non-static attribute belongs to one object.

Example:

private String reportName;

Every object has its own value.

PatientReport reportOne = new PatientReport();
PatientReport reportTwo = new PatientReport();

Memory idea:

Heap:
PatientReport object 1
    reportName

PatientReport object 2
    reportName

Non-static attributes are stored as part of each object in heap memory.


Static vs Non-Static Summary

Feature Static Non-static
Belongs to Class Object
Number of copies One shared copy One copy per object
Object required No Yes
Shared between objects Yes No
Lifetime Usually while class is loaded While object is reachable
Can cause long-lived references Yes Less likely unless object is retained
Attribute data Shared class-associated value Stored inside each object

Static Method and Heap Memory

A static method does not belong to an object.

Example:

public static Patient createPatient() {
    return new Patient();
}

The method itself does not create a permanent stack or heap area.

When the method runs:

  • A stack frame is created.
  • new Patient() creates a Patient object in heap memory.
  • The reference is returned.

Example:

Patient patient = PatientFactory.createPatient();

Memory idea:

Stack:
patient reference

Heap:
Patient object

Non-Static Method and Heap Memory

A non-static method belongs to an object.

Example:

public String getPatientName() {
    return patientName;
}

The object and its attribute patientName are in heap memory.

When the method runs:

  • A stack frame is created.
  • The current object reference this is available.
  • The method reads the object's heap data.

HMIS-Style Example

public class InvestigationReport {

    private static int totalReportsGenerated;

    private Department department;
    private Investigation investigation;

    private List<PatientInvestigation> results =
            new ArrayList<>();

    public void generateReport() {
        totalReportsGenerated++;

        results.add(new PatientInvestigation());
    }

    public static int getTotalReportsGenerated() {
        return totalReportsGenerated;
    }
}

Memory idea:

Heap:
InvestigationReport object
    department
    investigation
    results reference

ArrayList object
PatientInvestigation objects

Shared static data:
totalReportsGenerated

Heap and Stack Working Together

Example:

public void processPatient() {
    int count = 1;
    Patient patient = new Patient();
    patient.setPatientCode("P001");
}

Memory idea:

Stack:
count = 1
patient reference

Heap:
Patient object
    patientCode = "P001"

The stack stores temporary method data.

The heap stores the object and its non-static attributes.


Sensitive Data in Heap Memory

HMIS objects may contain sensitive data.

Examples:

private String patientName;
private String diagnosis;
private String investigationResult;

Sensitive objects may remain in heap memory while they are reachable.

Avoid:

  • Unnecessary static patient collections
  • Long-lived references to patient data
  • Caching sensitive values without a clear need
  • Storing passwords as plain text
  • Keeping large report results longer than required

Example of a risky static collection:

private static final List<Patient> allPatients =
        new ArrayList<>();

This collection may remain for the full application lifetime and prevent patient objects from being garbage collected.


Best Practices

  1. Remove references to objects that are no longer needed.
  2. Avoid unnecessary static collections.
  3. Clear large result lists when they are no longer required.
  4. Do not create objects repeatedly inside unnecessary loops.
  5. Use pagination for large reports.
  6. Avoid loading full entity graphs when a DTO is enough.
  7. Do not store sensitive patient data longer than necessary.
  8. Use appropriate bean scopes.
  9. Avoid memory leaks caused by long-lived references.
  10. Monitor heap usage in large HMIS reports.

Important Points

  1. Objects are stored in heap memory.
  2. Arrays are stored in heap memory.
  3. Collections are stored in heap memory.
  4. Non-static attributes are stored inside objects.
  5. Static fields are shared by the class.
  6. A static reference can keep a heap object alive.
  7. Garbage collection removes unreachable objects.
  8. Too many reachable objects may cause OutOfMemoryError.
  9. Stack references can point to heap objects.
  10. Heap memory is shared between threads.

Summary

Heap memory stores Java objects and their non-static attributes.

Example:

Patient patient = new Patient();

Memory idea:

Stack:
patient reference

Heap:
Patient object

Static and non-static difference:

Static:
One shared value belonging to the class.

Non-static:
One value per object stored as part of the object.

Main heap contents:

Objects
Arrays
Collections
String objects
Non-static attributes
Shared referenced data

Clone this wiki locally