diff --git a/README.md b/README.md index e91e655..8fa3cb5 100644 --- a/README.md +++ b/README.md @@ -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 ` 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 ` 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 ` 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 ` 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). \ No newline at end of file