한국어English日本語简体中文繁體中文DeutschไทยTiếng ViệtРусскийPortuguês (Brasil)EspañolBahasa Indonesia

Game Lag White Paper › L10 Memory

GC thrashing (too little heap headroom) GC thrashing (heap nearly full)

Cause ID mem-gc-thrash · Primary owner Game team (Server development) · Also Infra team (Server infrastructure)

Open the interactive card with figures and simulations →

When live data gets close to the heap limit, each GC reclaims almost nothing, so GC runs over and over without a break.

Why An event crowd or a leak pushes live data close to the heap limit → Effect GC reclaims only a little, so another full GC follows right away and GC uses most of the CPU → On screen The whole server alternates between slow motion and freezes for several minutes, then dies from running out of memory

Symptoms
Slow motion, Freeze, Disconnect
Factors
Stall
Who’s affected
Whole server
When
Evening peak hours, When crowds gather, The longer it runs
Owner
Primary owner Game team (Server development) · Also Infra team (Server infrastructure)
Game team action items
Size the heap well above peak live data (usually 2× or more), reduce long-held references and leaks.
Infra team action items
Alert on GC time ratio, restart promptly without waiting for it to recover, use instances with enough memory to grow the heap.
Ballpark numbers
GC taking more than 10% of run time is usually treated as a warning sign. Some Java GCs throw an out-of-memory error when they spend 98% of the time in GC and still reclaim almost nothing.
On the graph
Hits a ceiling · Heap after GC, GC time ratio
Where to look
How close the heap left after GC is to the max heap, and the share of time spent in GC. Java: “after GC (heap size)” in -Xlog:gc lines and how often Pause Full lines appear. .NET: dotnet-counters (% Time in GC since last GC on .NET 8 and earlier, growth of dotnet.gc.pause.time on .NET 9 and later). Go: the interval between GODEBUG=gctrace=1 lines
Confirmed if
The heap stays near its max even right after GC, full GCs run back to back, and the GC time ratio climbs well above normal (usually past 10%). Ticks slow down across the whole server meanwhile
Ruled out if
Plenty of heap left after GC but pauses are long: GC type or settings (mem-gc)
Check with
Infra tools (no game code needed)

Sources

  1. The Parallel Collector Oracle
    Parallel GC throws OutOfMemoryError if it spends more than 98% of total time in GC and recovers less than 2% of the heap
  2. Garbage-First Garbage Collector Tuning Oracle
    By default (GCTimeRatio=12), G1 sizes the heap to keep GC time at about 8% of total time or less; full GCs caused by excessive heap occupancy show up in the log as Pause Full (G1 Compaction Pause)
  3. A Guide to the Go Garbage Collector Go
    With the default GOGC=100, the heap goal is about 2× the live heap; near the memory limit, GC runs nonstop (thrashing); GODEBUG=gctrace=1 prints GC trace output
  4. Garbage Collector Implementation Oracle
    -Xlog:gc lines show the GC type (Pause Young, Pause Full), “before-GC usage->after-GC usage(heap size)”, and the pause time
  5. dotnet-counters diagnostic tool .NET
    .NET 9 and later show dotnet.gc.pause.time; .NET 8 and earlier show % Time in GC since last GC

See also

Same layer: L10 Memory

Same symptom (Slow motion), other layers

View the interactive card with figures and simulations