Skip to content

Fix memory leaks and concurrency issues in menu bar item caching#841

Closed
stonerl wants to merge 4 commits into
jordanbaird:macos-26from
stonerl:memory-leak
Closed

Fix memory leaks and concurrency issues in menu bar item caching#841
stonerl wants to merge 4 commits into
jordanbaird:macos-26from
stonerl:memory-leak

Conversation

@stonerl

@stonerl stonerl commented Jan 6, 2026

Copy link
Copy Markdown
Contributor

This PR addresses several memory leaks and concurrency issues in the menu bar item caching system. It is based on PR #804 by @mrunkel

  • Fix memory leaks in cache:

    • Added pruneUUIDCache to MenuBarItemTag.Namespace to remove stale UUID entries for windows that no longer exist, preventing unbounded growth.
    • Added pruneMoveOperationTimeouts to MenuBarItemManager to clean up old timeout values for items that are no longer managed.
    • Corrected cleanup logic in MenuBarItemImageCache to properly access managedItems and remove stale images, fixing a build error and potential leak.
  • Fix concurrency issues:

    • Enforced @MainActor isolation on MenuBarItem and MenuBarItemTag initializers.
    • Propagated @MainActor requirements to getMenuBarItems and helper methods to ensure thread-safe access to shared static caches and prevent data races.

mrunkel and others added 4 commits January 6, 2026 18:24
On long running systems, the cache would continue to grow.

On my system, after running for 15 days, the Cache 983MB, almost of the total memory usage.

(cherry picked from commit e86993f)
- Correctly access `managedItems` instead of the non-existent `allItems` property on `ItemCache`.
- Map items to their `tag` property to correctly filter the `images` dictionary, which is keyed by `MenuBarItemTag`.
- This ensures stale images are properly removed from the cache without causing build failures.
- Add `pruneUUIDCache` method to `MenuBarItemTag.Namespace` to remove stale entries from the static `uuidCache`.
- Call `pruneUUIDCache` in `MenuBarItemManager` during cache updates to ensure the cache only retains data for active windows.
- Prevents unbounded growth of the UUID cache over time.
…m creation

- Mark `MenuBarItem` and `MenuBarItemTag` initializers as `@MainActor` to ensure safe access to the static `uuidCache`.
- Propagate `@MainActor` requirement to `getMenuBarItems` and its helper methods to resolve isolation errors.
- This ensures all static cache access and item creation occurs on the main thread, preventing data races.
cp09x added a commit to cp09x/icebar that referenced this pull request Jan 24, 2026
Critical Improvements:
1. Safety: Replace force unwraps in Constants.swift with safe defaults
   - Prevents crashes if Info.plist is misconfigured
   - Adds fallbacks: versionString, buildString, bundleIdentifier, etc.

2. Performance: Add removeDuplicates() to overlay panel publishers
   - Prevents unnecessary redraws when applicationMenuFrame hasn't changed
   - Optimizes desktop wallpaper comparison using CGImage data
   - Estimated impact: 30-40% reduction in unnecessary UI updates

3. Performance: Reduce wallpaper polling from 5s to 15s
   - Desktop wallpaper capture is expensive (CGImage creation)
   - 3x reduction in polling frequency
   - Estimated impact: Reduces CPU usage and energy consumption

Build: Verified with xcodebuild - BUILD SUCCEEDED

Based on analysis of:
- Upstream PRs jordanbaird#842, jordanbaird#841 (CPU/memory optimization patterns)
- Code analysis by explore agents (found force unwraps, missing removeDuplicates)
- Oracle strategic planning (prioritized high-impact, low-risk fixes)
cp09x added a commit to cp09x/icebar that referenced this pull request Jan 25, 2026
Memory leak prevention from upstream PR jordanbaird#841 patterns:

1. UUID Cache Pruning (MenuBarItem.swift):
   - Added pruneUUIDCache() to remove stale window ID entries
   - Made Namespace extension public to allow pruning calls
   - Prevents unbounded growth of UUID-to-windowID mappings

2. Image Cache Pruning (MenuBarItemImageCache.swift):
   - Filter images dict to only keep valid entries after merge
   - Removes stale cached images that no longer have menu bar items
   - Prevents memory accumulation over app lifetime

Combined Impact:
   - Prevents memory leaks during extended app usage
   - Cleans up caches when menu bar items are removed
   - More stable long-running performance

Build: Release configuration - BUILD SUCCEEDED
@stonerl stonerl closed this by deleting the head repository Jan 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants