@@ -63,6 +63,7 @@ import kotlinx.coroutines.Dispatchers
6363import kotlinx.coroutines.delay
6464import kotlinx.coroutines.flow.first
6565import kotlinx.coroutines.launch
66+ import kotlinx.coroutines.withContext
6667import org.jetbrains.compose.resources.DrawableResource
6768import org.jetbrains.compose.resources.painterResource
6869import java.util.concurrent.atomic.AtomicLong
@@ -121,6 +122,29 @@ private val defaultVerticalOffset =
121122 }
122123 }
123124
125+ private const val GC_AFTER_HIDE_DELAY_MS = 1_500L
126+
127+ /* *
128+ * Trims the heap after the popup leaves the screen. The popup keeps its
129+ * composition alive while hidden (so state survives hide/show), which means
130+ * garbage from the visible session otherwise lingers for as long as the app
131+ * idles in the tray — exactly the footprint users check in the task manager.
132+ * Right after the exit animation there is no UI on screen, so the collection
133+ * pause is invisible.
134+ *
135+ * Must be called from the visibility `LaunchedEffect`: reshowing the popup
136+ * restarts the effect and cancels the [delay], debouncing rapid toggles for
137+ * free. The collection runs off the UI thread so the tray loop only pays the
138+ * stop-the-world portion.
139+ */
140+ private suspend fun requestGcWhileHidden () {
141+ delay(GC_AFTER_HIDE_DELAY_MS )
142+ withContext(Dispatchers .Default ) {
143+ @Suppress(" ExplicitGarbageCollectionCall" )
144+ System .gc()
145+ }
146+ }
147+
124148// --------------------- Public API (overloads) ---------------------
125149
126150@Composable
@@ -661,6 +685,7 @@ private fun TrayAppImplPanel(
661685 snapshotFlow { visibleState.isIdle && ! visibleState.currentState }.first { it }
662686 popupOnScreen = false
663687 lastHiddenAtMs.set(System .currentTimeMillis())
688+ requestGcWhileHidden()
664689 }
665690 }
666691 }
@@ -851,6 +876,7 @@ private fun NucleusApplicationScope.TrayAppImplWindow(
851876 snapshotFlow { visibleState.isIdle && ! visibleState.currentState }.first { it }
852877 shouldShowWindow = false
853878 lastHiddenAtMs.set(System .currentTimeMillis())
879+ requestGcWhileHidden()
854880 }
855881 }
856882 }
0 commit comments