Trim image and trust-score caches on memory pressure

Coil 3 registers no ComponentCallbacks of its own, so its 32MB bitmap
memory cache stayed fully resident in this long-lived signer process
even with the UI invisible and under system memory pressure.

onTrimMemory now clears the Coil memory cache on TRIM_MEMORY_UI_HIDDEN
and, additionally, TrustScoreService's cache from
TRIM_MEMORY_BACKGROUND up. Since API 34 the deprecated RUNNING_*/
MODERATE/COMPLETE levels are never delivered, so onLowMemory is
overridden as the foreground-pressure stand-in (verified against the
SDK 36 android.jar: only UI_HIDDEN and BACKGROUND are non-deprecated).

Also ignores the local trace_processor wrapper downloaded for the
heapprofd profiling session.
This commit is contained in:
greenart7c3
2026-08-21 06:01:15 -03:00
parent 591ed2324d
commit 09aeb733e6
2 changed files with 41 additions and 0 deletions
+2
View File
@@ -137,3 +137,5 @@ lint/tmp/
# lint/reports/
quartz/
.ai-jail
trace_processor
perf-traces
@@ -54,6 +54,7 @@ import com.greenart7c3.nostrsigner.service.ConnectivityService
import com.greenart7c3.nostrsigner.service.NotificationSubscription
import com.greenart7c3.nostrsigner.service.ProfileSubscription
import com.greenart7c3.nostrsigner.service.TorManager
import com.greenart7c3.nostrsigner.service.TrustScoreService
import com.greenart7c3.nostrsigner.service.UpdateCheckWorker
import com.greenart7c3.nostrsigner.service.ZapstoreUpdater
import com.greenart7c3.nostrsigner.service.crashreports.CrashReportCache
@@ -630,6 +631,44 @@ class Amber :
.build()
}
override fun onTrimMemory(level: Int) {
super.onTrimMemory(level)
// Since API 34 the system only delivers UI_HIDDEN and BACKGROUND here —
// the RUNNING_*/MODERATE/COMPLETE levels are deprecated and never sent.
// UI_HIDDEN (20) is not pressure, but a long-lived signer process has no
// reason to keep UI-only caches while its UI is invisible either.
if (level == TRIM_MEMORY_UI_HIDDEN) {
trimImageMemoryCache()
} else if (level >= TRIM_MEMORY_BACKGROUND) {
trimImageMemoryCache()
TrustScoreService.clearCache()
}
}
/**
* Pre-API-34 stand-in for foreground memory pressure (the deprecated
* TRIM_MEMORY_RUNNING_* levels are never delivered since API 34): the
* system only calls this when memory is low enough that process death is
* imminent.
*/
override fun onLowMemory() {
super.onLowMemory()
trimImageMemoryCache()
TrustScoreService.clearCache()
}
private fun trimImageMemoryCache() {
// Coil 3 registers no ComponentCallbacks of its own, so its bitmap
// memory cache (32 MB cap) would otherwise stay fully resident in
// this long-lived signer process even while its UI is not visible.
// The cache rebuilds lazily on the next image load.
applicationIOScope.launch {
runCatching { SingletonImageLoader.get(this@Amber).memoryCache?.clear() }
.onFailure { AmberLog.w(TAG, "Failed to trim Coil memory cache", it) }
}
}
override fun onTerminate() {
super.onTerminate()
applicationIOScope.cancel()