Save 50–115 MB — dispose leaked Tone.js synths & reset audio buffers#5928
Merged
walterbender merged 1 commit intosugarlabs:masterfrom Mar 8, 2026
Merged
Conversation
Contributor
|
✅ All Jest tests passed! This PR is ready to merge. |
…dio memory - Add .dispose() calls before deleting instruments in ___createSynth() for BUILTIN_SYNTHS, CUSTOM_SYNTHS, and CUSTOMSAMPLES code paths - Add disposeAllInstruments() method to Synth that properly disposes all instruments, filters, and effects for every turtle - Call disposeAllInstruments() in Logo.doStopTurtles() to free decoded AudioBuffers and Web Audio nodes when the stop button is pressed - Close AudioContext in testTuner() and testSpecificFrequency() to prevent orphaned audio resource leaks (~4-8 MB each) - Reset unbounded data structures (turtleHeaps, turtleDicts, notationNotes, _midiData, statusFields, specialArgs, connectionStore, recordingBuffer) at the start of runLogoCommands() to free memory between repeated runs - Update test mocks to include disposeAllInstruments Estimated RAM savings: ~65-145 MB depending on session length and number of instruments loaded.
a267c03 to
26ec0af
Compare
Contributor
|
✅ All Jest tests passed! This PR is ready to merge. |
Contributor
Author
|
@walterbender did a browser testing works fine |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes audio memory leaks where Tone.js instruments and Logo data structures were never freed, causing RAM usage to grow ~50–115 MB over a session.
Problem
___createSynth()callsdelete instruments[turtle][name]to replace instruments but never calls.dispose()first. Each undisposedTone.Sampler/Tone.Synthretains decoded AudioBuffers (~1–4 MB each).doStopTurtles()stops sounds but never frees the underlying Tone.js nodes, so every Play→Stop cycle leaks all instrument memory.runLogoCommands()never resetsturtleHeaps,turtleDicts,notationNotes,_midiData,statusFields,specialArgs,connectionStore, orrecordingBufferbetween runs, so they grow indefinitely.Changes
js/utils/synthutils.js (+83)
___createSynth()— Added.dispose()calls (with try/catch) beforedelete instruments[turtle][instrumentName]for BUILTIN_SYNTHS, CUSTOM_SYNTHS, and CUSTOMSAMPLES code pathsdisposeAllInstruments()method — Iterates all turtles and properly.dispose()s every instrument, filter, and effect ininstruments,instrumentsFilters, andinstrumentsEffectsjs/logo.js (+24)
disposeAllInstruments()indoStopTurtles()aftersynth.stop()— frees all decoded AudioBuffers and Web Audio nodes when the user presses Stop. Instruments are re-created byprepSynths()on the next run.runLogoCommands()— clearsturtleHeaps,turtleDicts,notationNotes,_midiData,statusFields,specialArgs,connectionStore, andrecordingBuffer(only when not actively recording)js/tests/logo.test.js (+6)
disposeAllInstruments: jest.fn()to all 5 synth mock objects sodoStopTurtlestests passEstimated RAM Savings
___createSynthTesting
Automated
npx eslint js/utils/synthutils.js js/logo.js js/__tests__/logo.test.js— 0 errorsnpx prettier --check— all files passnpx jest js/__tests__/logo.test.js --no-coverage— 42/42 tests passBrowser Testing (8+ Play→Stop cycles)
disposeAllInstrumentsexists ✅prepSynths()✅Edge Cases Verified
recordingBufferis preserved whenthis.recordingis true