The Memory Exhaustion Problem
In this design, every object keeps all of its own data, even when most of that data is the same as in other objects. In large programs, such as a global map or a forest in a video game, this "Heavyweight" approach uses a huge amount of memory and can crash the program.
1. Real-Life Coding Example
Imagine you are building a feature like Google Maps that shows millions of trees across the globe. There are millions of trees, but most of them belong to only a few types like "Oak", "Pine", or "Birch".
Suppose we create a separate object for each tree, and each one stores its own tree type, color, and texture. This causes:
- Redundant memory usage: Storing the string "Oak" and "Green" 1 million times.
- Inefficient rendering: The graphics engine has to handle 1 million separate data sets instead of 1 shared one.
- High GC Overhead: The Garbage Collector (the cleanup of unused objects) must track 1 million objects, which causes "stutters" (short pauses).
2. Key Issues in this Design
Lack of State Separation (Intrinsic vs. Extrinsic)
- The Issue: The code puts Intrinsic state (data that never changes, like
name,color,texture) and Extrinsic state (data that differs per tree, likexandy) in the same class. - The Impact: Because they are bundled together, we cannot share the constant data. Every time a new tree is planted, the whole data set is copied again.
Massive Memory Footprint
- The Issue: 1 million
Treeobjects means 1 million copies of the same strings and metadata. - The Impact: The repo code assumes the type data of one tree takes about 1KB, so 1 million trees consume ~1GB of RAM. This number is illustrative, not measured. In a complex game with billions of objects, the program soon fails with
OutOfMemoryError(the JVM has run out of memory).
Heavy Object Headers
- The Issue: In languages like Java, every object has a header (extra bookkeeping data) of 12-16 bytes.
- The Impact: For 1 million trees, you spend ~16MB just on headers, whatever the data inside. The bookkeeping costs more than the data it describes.
Slower Rendering & GC Pressure
- The Issue: There are so many separate objects and references that the system slows down.
- The Impact: Creating objects this fast keeps the Garbage Collector busy, so the program lags while it manages millions of small, repeated objects.
3. Structural Analysis
| Component | Status | Observation |
|---|---|---|
| Tree Object | Heavyweight | Carries redundant strings ("Oak", "Rough") in every instance. |
| Forest Collection | Bloated | Holds 1 million unique references instead of a few shared types. |
| Client Logic | Inflexible | No factory or cache mechanism to check if a "type" already exists. |
4. Summary of the "Smell"
Watch for this: the program handles a huge number of objects, and most of their data is the same. That is a memory problem. The old code created a new Tree object for every request, so shared data was copied each time. The Flyweight Pattern fixes this by sharing the "intrinsic" state across all instances.