Real‑world examples of OutOfMemoryError: key examples explained

If you work with Java, Android, or big data systems long enough, you will eventually hit an OutOfMemoryError. And when it happens, the stack trace often feels like it’s trolling you. That’s why walking through real, concrete examples of OutOfMemoryError: key examples explained in context is far more useful than reading a dry definition. In this guide, we’ll stay practical. We’ll look at real examples of OutOfMemoryError from server‑side Java, Spring Boot microservices, Android apps, data processing jobs, and even containerized deployments. We’ll unpack what actually went wrong in memory terms, how developers diagnosed it, and what they changed to fix it. Along the way, you’ll see patterns: unbounded collections, leaky caches, massive images, misconfigured JVM options, and memory‑hungry libraries. If you’ve ever stared at `java.lang.OutOfMemoryError: Java heap space` or `GC overhead limit exceeded` and wondered what to do next, these examples will give you a clearer mental model and a practical debugging checklist.
Written by
Jamie
Published

Let’s start where it hurts: real outages. When engineers talk about examples of OutOfMemoryError: key examples explained in postmortems, the same themes keep coming up—unbounded growth, bad defaults, and blind trust in libraries.

Consider a typical microservice running in Kubernetes. It’s given 512 MB of heap, because someone copied a Helm chart from Stack Overflow. Traffic grows, a new feature adds JSON logging with full request bodies, and suddenly the service crashes with java.lang.OutOfMemoryError: Java heap space. The root cause? A logging wrapper buffering entire payloads in memory before writing them.

Or an Android app that looks fine in testing but crashes on older devices with less RAM. On those devices, a single screen with several high‑resolution images triggers java.lang.OutOfMemoryError: Failed to allocate a XYZ byte allocation. Under the hood, bitmaps are eating the heap alive.

These are not rare edge cases. They’re the best examples of how small design decisions snowball into memory failures.


Classic server‑side example of OutOfMemoryError: Java heap space

The most common example of OutOfMemoryError on the JVM is the plain Java heap space failure. The pattern is boring but deadly: a collection that grows without an upper bound.

Imagine a Spring Boot API that reads messages from Kafka and temporarily stores them in a List before batch processing. Under load, the consumer falls behind. Instead of back‑pressuring or throttling, the code keeps adding to the list. Heap usage climbs steadily until the JVM can’t allocate more objects, and you see:

java.lang.OutOfMemoryError: Java heap space

In real examples of OutOfMemoryError like this, the heap dump usually shows one or two giant collections holding millions of objects. Tools like Eclipse Memory Analyzer (MAT) or VisualVM make this painfully obvious.

Fix patterns you see in these examples include:

  • Introducing back‑pressure (e.g., limiting queue size, pausing consumers)
  • Streaming processing instead of buffering everything in memory
  • Using bounded collections (e.g., LinkedBlockingQueue with a max size)
  • Raising heap size only after you’ve verified there is no leak

A good reference for JVM tuning basics, which often shows up in these situations, is the official OpenJDK documentation and Oracle’s Java memory tuning guides: https://docs.oracle.com/javase/8/docs/technotes/guides/vm/gctuning/ .


Examples of OutOfMemoryError: key examples explained in caching and singletons

Another cluster of examples of OutOfMemoryError comes from well‑intentioned caching. Developers add an in‑memory cache to speed up database calls and forget to set an eviction policy.

Picture a singleton ConcurrentHashMap<String, UserProfile> keyed by user ID. The system has millions of users. The cache never evicts. Over a few hours, every active user gets loaded and stored forever. Heap usage climbs until the application dies.

In these real examples, the heap dump shows the cache map dominating memory. Sometimes the real villain is a library‑provided cache with a dangerous default, like storing full response bodies or ORM entities with deep object graphs.

Patterns you repeatedly see in these key examples explained by engineers:

  • Replacing raw maps with LRU/LFU caches (Caffeine, Guava Cache) with maximum size
  • Using time‑based eviction for stale entries
  • Moving large caches to external systems like Redis or Memcached
  • Ensuring singletons don’t hold references to large graphs longer than needed

These examples of OutOfMemoryError are less about raw memory limits and more about lifecycle: data that should die but doesn’t.


Android and UI: examples include bitmap and image allocation failures

Mobile developers have their own flavor of pain. Common examples of OutOfMemoryError: key examples explained in Android revolve around images.

A very typical example of OutOfMemoryError on Android:

  • A RecyclerView shows a grid of photos.
  • Each photo is loaded at full camera resolution.
  • Bitmaps are kept in memory while the user scrolls.

On a high‑end phone with plenty of RAM, this might limp along. On a mid‑range or older phone, you get:

java.lang.OutOfMemoryError: Failed to allocate a XXXX byte allocation with XXXX free bytes and XXXX until OOM

Real‑world fixes in these Android examples include:

  • Downsampling images to screen resolution instead of original size
  • Using libraries like Glide or Picasso with proper caching and pooling
  • Clearing or canceling image requests when views are recycled
  • Moving large images off the main heap (e.g., using hardware bitmaps where appropriate)

Google’s Android developer docs have good, practical guidance on memory management and bitmap handling: https://developer.android.com/topic/performance/memory . These docs line up very closely with field reports and Stack Overflow threads about OutOfMemoryError on Android.


Container and cloud examples of OutOfMemoryError: JVM vs cgroup limits

A newer set of examples of OutOfMemoryError: key examples explained in 2024–2025 comes from containerized deployments. The JVM historically didn’t always respect container memory limits; modern versions are better, but misconfigurations still cause nasty surprises.

A realistic scenario:

  • A Java service is deployed in Docker with --memory=512m.
  • The JVM is started with -Xmx1g because that’s copied from a legacy VM.
  • The JVM happily tries to use up to 1 GB of heap, but the container is killed by the kernel’s OOM killer when it crosses ~512 MB.

In logs, you might see OutOfMemoryError or just abrupt container termination. In Kubernetes, this shows up as OOMKilled restarts.

Recent examples include teams migrating to Java 17+ and assuming the JVM will automatically “do the right thing” with container limits. It often does a better job than older versions, but explicit configuration is still necessary.

Common mitigation patterns in these examples include:

  • Setting -XX:MaxRAMPercentage and -XX:InitialRAMPercentage to align heap with container limits
  • Leaving headroom for non‑heap memory: native memory, direct buffers, threads, JIT, and libraries
  • Monitoring container memory usage at the orchestrator level (Kubernetes metrics, Prometheus, etc.)

The OpenJDK wiki and official docs on container awareness are worth a read for anyone deploying Java in Docker: https://openjdk.org/jeps/343 .


Data processing and streaming: GC overhead and OutOfMemoryError examples

Big data platforms like Spark, Flink, and Kafka Streams provide some of the best examples of how OutOfMemoryError manifests when you push the JVM hard with large datasets.

A typical Spark example of OutOfMemoryError:

  • A job performs a wide groupByKey on a massive dataset.
  • Data for a single key is skewed and far larger than expected.
  • Spark tries to materialize a huge collection in memory on a single executor.

The executor log shows:

java.lang.OutOfMemoryError: GC overhead limit exceeded

This specific variant means the JVM is spending almost all of its time in garbage collection and still not freeing enough memory. In real examples, memory usage graph looks like a sawtooth pattern glued to the top of the heap.

Patterns repeated across these data‑platform examples include:

  • Replacing groupByKey with reduceByKey or aggregateByKey to avoid pulling all values into memory
  • Increasing executor memory and adjusting Spark’s memory fractions
  • Fixing data skew so that a single partition doesn’t become a memory time bomb
  • Using off‑heap storage or disk‑backed shuffles when appropriate

Apache’s official docs for Spark and Flink include tuning pages that map very directly to these OutOfMemoryError examples: https://spark.apache.org/docs/latest/tuning.html .


ClassLoader and Metaspace: more subtle examples of OutOfMemoryError

Heap space is not the only arena. Modern JVMs replaced PermGen with Metaspace, but you can still get:

`text java.lang.OutOfMemoryError: Metaspace

This usually shows up in long‑running servers or app servers that load and unload applications dynamically. Real examples of OutOfMemoryError in this category include:

  • An application server (Tomcat, WebLogic, etc.) redeploying an app repeatedly without a full restart
  • A plugin system that creates a new ClassLoader per plugin but never unloads old ones
  • Bytecode‑generating frameworks (ORMs, proxies, dynamic code) leaking classes

In these examples, heap dumps are less useful than jcmd and jmap metadata reports, which show the number of loaded classes and ClassLoaders. The fix is almost always to ensure ClassLoaders can be garbage‑collected by removing static references and cleaning up threads and caches that hold onto classes.

Again, Oracle’s and OpenJDK’s documentation on Metaspace tuning gives you the knobs you can adjust, but the real fix is almost always a leak, not just a limit.


Diagnosing patterns across examples of OutOfMemoryError: key examples explained

If you look across all these examples of OutOfMemoryError: key examples explained, certain diagnostic steps repeat regardless of framework or platform.

Developers who share real examples usually follow a pattern like this:

  • Capture heap dumps on OutOfMemoryError (-XX:+HeapDumpOnOutOfMemoryError and -XX:HeapDumpPath)
  • Use a memory analyzer (Eclipse MAT, VisualVM, YourKit, JProfiler) to find the biggest objects and paths to GC roots
  • Check for unbounded collections, caches, or queues
  • Look at thread dumps for evidence of blocked or stuck threads holding memory
  • Correlate memory graphs with traffic, batch jobs, or deployments

These steps are not glamorous, but they explain why the best examples of OutOfMemoryError debugging stories almost always end with “we found a single map/list/cache holding way more data than expected.”

For health‑style thinking about diagnostics and root‑cause analysis (even though it’s a different domain), resources like the National Institutes of Health’s guidance on systematic diagnosis are surprisingly relevant in spirit: https://www.nih.gov/ . Good debugging borrows heavily from that kind of structured thinking.


Preventive practices inspired by real examples of OutOfMemoryError

When teams share examples of OutOfMemoryError: key examples explained in retrospectives, the action items tend to converge on a few preventive habits:

  • Set explicit limits. Bounded queues, capped caches, and well‑defined JVM heap settings prevent many of the worst examples.
  • Load test with realistic data. Synthetic tests rarely expose the skew, large payloads, or image sizes that cause real failures.
  • Monitor memory as a first‑class metric. Heap usage, GC pauses, and container memory consumption should be on dashboards and alerts.
  • Review third‑party libraries. Some of the nastiest examples include hidden caches, in‑memory logs, or buffering behavior inside dependencies.
  • Educate the team. Sharing internal postmortems and external case studies helps newer engineers recognize the smell of an impending OutOfMemoryError.

Interestingly, this is similar to how public‑health organizations like the CDC talk about prevention versus treatment: patterns, monitoring, and early intervention. While they’re discussing human health, the mindset is the same: https://www.cdc.gov/ .


FAQ: common questions about examples of OutOfMemoryError

Q1: What are the most common examples of OutOfMemoryError in Java applications?
The most common examples include unbounded collections (lists, maps, queues) that keep growing, in‑memory caches without eviction, image/bitmap handling in Android apps, misaligned JVM heap settings in containers, and data processing jobs that try to materialize huge datasets in memory. Real examples usually show a small number of objects or collections dominating the heap.

Q2: Can you give an example of OutOfMemoryError caused by a memory leak?
A classic example of OutOfMemoryError from a leak is a static Map used as a cache that never removes entries. Each request adds a new key, and nothing is ever evicted. Over time, the map grows until the JVM cannot allocate more objects and throws java.lang.OutOfMemoryError: Java heap space. Heap analysis reveals that the map is strongly referenced and holds almost all live objects.

Q3: How do I know if I should just increase heap size or fix code?
If a one‑time spike caused the failure and profiling shows no obvious leak, increasing heap might be reasonable. But if your heap usage grows steadily over time or scales linearly with traffic or data size, the real‑world examples say you almost always need a code or design change. Heap dumps and memory analyzers are the best way to distinguish between an undersized heap and a genuine leak.

Q4: Are OutOfMemoryError examples different on Java 8 vs Java 17+?
The patterns are similar, but you’ll see fewer PermGen errors on newer JVMs (replaced by Metaspace), better container awareness, and sometimes different GC behavior. Modern collectors like G1 and ZGC can change how symptoms appear (e.g., fewer long pauses), but the root causes in real examples—unbounded growth, leaks, and bad assumptions—are the same.

Q5: What’s the best way to reproduce an OutOfMemoryError example locally?
Use production‑like data and traffic patterns, set a smaller heap (-Xmx), and run your app under a profiler. Many teams take a real payload or dataset, replay it against a staging environment, and watch memory graphs. This mirrors the real examples of OutOfMemoryError you see in production without risking an actual outage.

Explore More Stack Overflow Errors

Discover more examples and insights in this category.

View All Stack Overflow Errors