Restructure README with headings
Move the weirdperformance note under Client mods, fix the install section wording, and point the tests section at tests/README.md. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019W3rwtugSE5NbbiWQCbbKX
This commit is contained in:
@@ -1,8 +1,12 @@
|
||||
Gentle Garbage Collection — unified edition (v2.7)
|
||||
---
|
||||
# Gentle GC
|
||||
|
||||
Gentle Garbage Collection, unified edition (v2.7).
|
||||
|
||||
For WoW 1.18.1 clients (Lua 5.0).
|
||||
|
||||
**Install**: unzip into `Interface/AddOns`. The zip has two folders:
|
||||
## Install
|
||||
|
||||
Unzip into `Interface/AddOns`. The zip has two folders:
|
||||
`GentleGC` (the addon) and `!!!!GentleGC_Memory` (optional, per-addon memory;
|
||||
see below). Keep both folder names exactly as they are. If you download the
|
||||
repository instead, move `!!!!GentleGC_Memory` out of the `GentleGC` folder
|
||||
@@ -18,17 +22,8 @@ collections and plans with the lowest one it has seen. A
|
||||
pause can't be made shorter, but it can be moved. GentleGC moves it to
|
||||
moments you won't notice.
|
||||
|
||||
- weirdperformance (WeirdUtils): supported. It replaces the game's collector:
|
||||
each cycle does one full mark, then frees memory in small chunks, setting
|
||||
the threshold to 128 KB above the memory in use between chunks. Gentle GC
|
||||
recognizes this (through `GetWeirdUtilsVersion`), doesn't count or log the
|
||||
chunks, never starts a collection in the middle of a cycle, lets the chunks
|
||||
keep running in combat, and uses the combat headroom only to keep the next
|
||||
cycle's full mark out of the fight. `/ggc` shows its cycles and chunks.
|
||||
Don't run it together with wow_turbo: both replace the same part of the
|
||||
game's collector.
|
||||
## When it collects
|
||||
|
||||
**When it collects**
|
||||
- Loading screens, logging out, death/release, AFK, flight masters, and when you
|
||||
open a merchant, bank, mailbox, auction house or trainer.
|
||||
- Right after combat ends, if enough garbage built up.
|
||||
@@ -41,7 +36,9 @@ moments you won't notice.
|
||||
3 seconds out of combat. When the camera isn't moving, a hitch is much
|
||||
harder to notice. GentleGC detects ClassicAPI and works the same without it.
|
||||
|
||||
**Careful mode**: when collections average 100 ms or more (large addon
|
||||
## Careful mode
|
||||
|
||||
when collections average 100 ms or more (large addon
|
||||
memory without wow_turbo, typically 250-400 ms in raids), a pause is visible
|
||||
even while standing still. GentleGC then stops collecting while standing
|
||||
still or idle, and only collects at loading screens, death and release,
|
||||
@@ -49,7 +46,8 @@ taxis, NPC windows (merchant, bank, mail, auction house, trainer), AFK,
|
||||
after combat, and under pressure. It switches back once collections average
|
||||
under 75 ms. `/ggc slow <ms>` sets the limit; `/ggc slow 0` turns it off.
|
||||
|
||||
**When it doesn't**
|
||||
## When it doesn't
|
||||
|
||||
- Never in combat. On entering combat it also raises the automatic-GC
|
||||
threshold (32 MB of extra room by default), so that collection is pushed past
|
||||
the end of the fight where possible, and restores the threshold afterwards.
|
||||
@@ -58,7 +56,8 @@ under 75 ms. `/ggc slow <ms>` sets the limit; `/ggc slow 0` turns it off.
|
||||
leaves less room than that). A pause costs about the same whether it frees
|
||||
1 MB or 50 MB, because scanning live data is most of the work.
|
||||
|
||||
**Commands**
|
||||
## Commands
|
||||
|
||||
- `/ggc`: status: how many *automatic* (unscheduled) collections happened,
|
||||
which are the ones that cause stutter; collections run by other addons, by
|
||||
name; the collector's measured threshold ratio; how long collections take
|
||||
@@ -74,7 +73,10 @@ under 75 ms. `/ggc slow <ms>` sets the limit; `/ggc slow 0` turns it off.
|
||||
collection off), `/ggc reset`.
|
||||
- The old `/run ggc_debug = 1` still works.
|
||||
|
||||
**Freeze detector** (off by default)
|
||||
## Freeze detector
|
||||
|
||||
Off by default.
|
||||
|
||||
- `/ggc hitch` reports any frame that takes longer than 250 ms (`/ggc hitch 500`
|
||||
sets a different limit, `/ggc hitch 0` turns it off). Each report says
|
||||
whether a garbage collection happened in that frame and whose it was:
|
||||
@@ -92,7 +94,9 @@ under 75 ms. `/ggc slow <ms>` sets the limit; `/ggc slow 0` turns it off.
|
||||
into a fixed 64-slot buffer and reads the clock and memory counter once
|
||||
per frame, allocating nothing until it has a freeze to report.
|
||||
|
||||
**Per-addon memory** (`/ggc addons`): the 1.12 client has no per-addon
|
||||
## Per-addon memory
|
||||
|
||||
`/ggc addons`: the 1.12 client has no per-addon
|
||||
memory numbers, only the size of the whole Lua heap. The optional
|
||||
`!!!!GentleGC_Memory` folder loads before every other addon (that's what the
|
||||
`!!!!` is for) and, each time another addon finishes loading, collects garbage
|
||||
@@ -112,7 +116,9 @@ interface and listed; load-on-demand addons that load during play aren't
|
||||
measured. Same approach as Salahaja's AddonMemory; use one or the other,
|
||||
since both together collect twice per addon.
|
||||
|
||||
**Addons that wrap `collectgarbage`**: if an addon that loads before Gentle GC
|
||||
## Addons that wrap `collectgarbage`
|
||||
|
||||
if an addon that loads before Gentle GC
|
||||
wraps `collectgarbage` and turns Gentle GC's collections into something else
|
||||
(for example, only moving the threshold to just above the memory in use, which
|
||||
makes the game collect again almost at once), Gentle GC says so once, names
|
||||
@@ -120,13 +126,17 @@ the addon when it can find it, and stops retrying. Threshold changes made by
|
||||
other addons are listed in `/ggc` and logged at `/ggc debug 2`. Pressure
|
||||
collections are skipped when there would be almost nothing to free.
|
||||
|
||||
**Pause vs garbage freed**: `/ggc` estimates how a collection's pause splits
|
||||
## Pause vs garbage freed
|
||||
|
||||
`/ggc` estimates how a collection's pause splits
|
||||
into a fixed part and a part per MB freed, from Gentle GC's own collections
|
||||
this session. It appears after 5 collections whose freed amounts differ by at
|
||||
least 5 MB. Timing is exact only while `/ggc debug` or the freeze detector is
|
||||
on; otherwise it's measured in steps of about 15 ms.
|
||||
|
||||
**Other addons' collections**: GentleGC wraps the global `collectgarbage`,
|
||||
## Other addons' collections
|
||||
|
||||
GentleGC wraps the global `collectgarbage`,
|
||||
so when another addon runs a collection (for example a "free memory after
|
||||
fights" option), it's timed, counted under that addon's name, and doesn't
|
||||
throw off GentleGC's estimates. An addon that kept its own copy of
|
||||
@@ -135,7 +145,9 @@ collections are still detected, because the game's collector can't fire
|
||||
while memory is well below the threshold, and are listed as "unknown addon".
|
||||
Calls that only query memory or set the threshold pass straight through.
|
||||
|
||||
**Garbage rate**: `/ggc` and the periodic summary show how fast garbage is
|
||||
## Garbage rate
|
||||
|
||||
`/ggc` and the periodic summary show how fast garbage is
|
||||
being created (MB/s). Above 10 MB/s (30 s average) you get a warning, at most
|
||||
every 10 minutes: at that rate no schedule can avoid frequent collections,
|
||||
and the fix is finding the addon that creates it (`/ggc hitch` shows which
|
||||
@@ -144,9 +156,19 @@ events the memory jumps follow).
|
||||
The best way to shorten the pauses themselves is still to run less addon memory.
|
||||
pfQuest, for example, can hold 100 MB while idle.
|
||||
|
||||
**Client mods**
|
||||
## Client mods
|
||||
|
||||
- ClassicAPI: supported, as above. Its once-per-frame timer also runs
|
||||
GentleGC's background check, in place of a frame OnUpdate.
|
||||
- weirdperformance (WeirdUtils): supported. It replaces the game's collector:
|
||||
each cycle does one full mark, then frees memory in small chunks, setting
|
||||
the threshold to 128 KB above the memory in use between chunks. Gentle GC
|
||||
recognizes this (through `GetWeirdUtilsVersion`), doesn't count or log the
|
||||
chunks, never starts a collection in the middle of a cycle, lets the chunks
|
||||
keep running in combat, and uses the combat headroom only to keep the next
|
||||
cycle's full mark out of the fight. `/ggc` shows its cycles and chunks.
|
||||
Don't run it together with wow_turbo: both replace the same part of the
|
||||
game's collector.
|
||||
- SuperWoW and nampower: compatible. Neither offers anything GentleGC needs.
|
||||
- wow_turbo: compatible, and recommended with a lot of addon memory. It
|
||||
keeps the client's threshold rule but makes each collection much faster
|
||||
@@ -155,14 +177,12 @@ pfQuest, for example, can hold 100 MB while idle.
|
||||
- UnitXP SP3: compatible. A February 2026 build briefly turned garbage
|
||||
collection off in combat, and the next build removed that.
|
||||
|
||||
**Tests** (`tests/`) run on stock Lua 5.0 with stubbed game functions:
|
||||
`lua5.0 tests/test_stock.lua GentleGC.lua` (likewise `test_classicapi.lua`,
|
||||
`test_combat_auto.lua`, `test_hitch.lua`, `test_factor.lua`, which
|
||||
simulates the client's 1.25x collector, and `test_raid.lua`, which covers
|
||||
careful mode, other addons' collections and the garbage rate), and
|
||||
`test_memory.lua`, which replays a login for the per-addon measurement
|
||||
(`lua5.0 tests/test_memory.lua GentleGC.lua "!!!!GentleGC_Memory/GentleGC_Memory.lua"`). The game never loads them.
|
||||
## Tests
|
||||
|
||||
Credits: original by MarcelineVQ (Weird Vibes). Event-driven collection from
|
||||
See [tests/README.md](tests/README.md). The game never loads them.
|
||||
|
||||
## Credits
|
||||
|
||||
Original by MarcelineVQ (Weird Vibes). Event-driven collection from
|
||||
jrc13245's fork; separate report timer from TheRealFayz's fork. Per-addon
|
||||
measurement method from Salahaja's AddonMemory (MIT).
|
||||
Reference in New Issue
Block a user