BLOCKING_EXECUTOR in ExecutorsRegistrar uses unbounded CachedThreadPool — causes 68+ threads on low-memory devices

Aperta
#7,899 1 commento 0 reazioni 0 assegnatari Vedi su GitHub

I maintainer di solito rispondono entro 1 giorno

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
4/5
Tempo stimato
3-5 giorni
Idoneità per principianti
52/100
Tipo di issue
Bug
Chiarezza
Abbastanza chiara
Stato di attività
Tranquilla
Stack tecnologico
android, java

Direzione di ricerca

Inizia in firebase-common/.../concurrent/ExecutorsRegistrar.java e verifica come viene creato e utilizzato BLOCKING_EXECUTOR. Confronta le opzioni ThreadPoolExecutor con limiti e LinkedBlockingQueue descritte nella issue, quindi riproduci lo scenario di memoria insufficiente oppure esamina i thread dump. Il lavoro è completato quando la creazione dei thread bloccanti è limitata, mentre il recupero dei thread inattivi e il comportamento dell’executor rimangono appropriati.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

api: core api: messaging

Description

ExecutorsRegistrar.BLOCKING_EXECUTOR uses Executors.newCachedThreadPool() with no upper bound on thread creation:

// firebase-common/.../concurrent/ExecutorsRegistrar.java
static final Lazy<ScheduledExecutorService> BLOCKING_EXECUTOR =
    new Lazy<>(
        () ->
            scheduled(
                Executors.newCachedThreadPool(
                    factory("Firebase Blocking", ...))));

On low-end Android devices (2GB RAM, 2 CPU cores), this creates 68+ "Firebase Blocking Thread" instances during normal app usage. Each thread consumes ~1MB of stack space, contributing to memory pressure that triggers the low memory killer (lmkd).

Environment

  • Firebase product: firebase-messaging 25.0.1 (only Firebase product in use; BLOCKING_EXECUTOR comes from the transitive firebase-common dependency)
  • Device: 2GB RAM / 2-core CPU (emulator configured to simulate low-end Android Go devices)
  • Android version: API 34

Evidence

Thread dump captured via Thread.getAllStackTraces() shows 68 threads named "Firebase Blocking Thread #0" through "Firebase Blocking Thread #67", all in TIMED_WAITING state:

"Firebase Blocking Thread #0"  TIMED_WAITING
"Firebase Blocking Thread #1"  TIMED_WAITING
...
"Firebase Blocking Thread #67" TIMED_WAITING

Shortly after, the process was killed by lmkd:

lowmemorykiller: reason: low watermark is breached and swap is low (276kB < 151960kB)
ActivityManager: Process has died: fg  TOP

The app was the foreground TOP process and was still killed due to system-wide memory exhaustion.

Comparison

On a higher-spec emulator (4+ cores, more RAM), the same executor creates ~37 "Firebase Blocking Thread" instances. The slower CPU on the 2GB device means tasks take longer to complete, so more threads pile up before they can be reused — the exact scenario where unbounded pools are most dangerous.

Suggested fix

Replace Executors.newCachedThreadPool() with a bounded ThreadPoolExecutor in ExecutorsRegistrar.BLOCKING_EXECUTOR:

static final Lazy<ScheduledExecutorService> BLOCKING_EXECUTOR =
    new Lazy<>(
        () ->
            scheduled(
                new ThreadPoolExecutor(
                    0,
                    Math.max(4, Runtime.getRuntime().availableProcessors()),
                    60L, TimeUnit.SECONDS,
                    new SynchronousQueue<>(),
                    factory("Firebase Blocking", ...))));

This caps thread creation while preserving the same idle-thread reaping behavior. A LinkedBlockingQueue alternative would allow tasks to queue safely when all threads are busy.

Lingua principale
Java
Stelle
2.6k
Fork
733
Merge medio
2g 15h
PR unite (30g)
72

Preparare l'ambiente

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di firebase/firebase-android-sdk

Tutte le issue di firebase/firebase-android-sdk

Issue simili

Altre issue su Java

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.