mojira.dev
MC-305091

Item models are retained after reloading resource packs

GuiRenderer retains references to item models that have been rendered in GUI after resource pack reloads, creating a memory leak that can lead to crashes. The item model retention is not dependent on the currently applied packs, so loading into strictly vanilla resources does not resolve the leak. This issue has existed since the relevant code was first introduced in 1.21.6.

Steps to Reproduce:

  1. Install spark or otherwise observe the internal state of GuiRenderer

  2. Place a few (for example 6) distinct items on your hotbar

  3. Change GUI scale to ensure clean state

  4. Run /spark heapsummary and observe 6 net.minecraft.client.gui.render.GuiRenderer$AtlasPosition instances

  5. Reload resources with F3+T (or perform multiple times)

  6. Run /spark heapsummary again and observe 12 instances (doubled or times however many reloads)

  7. Change GUI scale again

  8. Run /spark heapsummary and observe it returns to 6 instances

Expected Behavior: Resource pack reloads should invalidate the UI item atlas texture, ensuring all previously rendered items are discarded.

Actual Behavior: After resource pack reloads, new model instances with new identities are created. When rendered, these are treated as new items and added to the item atlas texture. The old model identities from before the reload remain in the map, preventing garbage collection of all previous model data.

Workaround: Changing GUI scale forcibly triggers invalidation allowing for garbage collection.

Code Analysis:

The GuiRenderer#atlasPositions map tracks which model identities have been rendered to which positions in the UI item atlas texture. This allows items to be rendered once and reused across frames.

The map and atlas textures are only invalidated via invalidateItemAtlas() in two scenarios:

  1. GUI scale change

  2. Atlas capacity exceeded requiring resize

Meanwhile, resource pack reloads are not handled. When resources reload, all models are recreated with new reference equality identities. The new identities don't match existing atlasPositions entries, so they're added fresh. The old identities remain as keys, holding strong references to all their associated model data (BakedQuad, ItemTransform, SpriteContents, etc.), preventing garbage collection.

Memory Impact: Testing with large resource packs shows dramatic increases:

  • BakedQuad: 610k → 10.5M instances

  • Vector3f: 290k → 7.5M instances

  • ItemTransform: 27k → 725k instances

  • SpriteContents: 10k → 163k instances

  • AtlasPosition: 12 → 168 instances

Spark reports for those numbers: First loaded a large pack, then after a dozen reloads, finally after changing GUI scale.

The leak is particularly severe for resource packs using traditional custom model data/range dispatch patterns, where viewing a single item causes all variant models to be leaked together.

Environment

Java Version: OpenJDK 21.0.7+6-LTS
OS: Windows 10 64-bit
System Memory: 16GB
JVM Memory: 2GB

Comments 0

No comments.

Paul Fulham

(Unassigned)

Plausible

Platform

Normal

Resource Packs, Textures and models

1.21.11

Retrieved