Skip to content

Conversation

@codegen-sh
Copy link
Contributor

@codegen-sh codegen-sh bot commented Dec 26, 2025

💧 Memory Leak в FloatingWindowService - ИСПРАВЛЕНО

⚠️ Найденная проблема

КРИТИЧНАЯ УТЕЧКА ПАМЯТИ:
При уничтожении FloatingWindowService (например, при закрытии через кнопку или системой при нехватке памяти) корутины продолжали выполняться в фоне, удерживая ссылку на Context сервиса.

Причина:

override fun onDestroy() {
    super.onDestroy()
    isDestroyed = true
    stopScript()
    handler.removeCallbacksAndMessages(null)
    // ❌ НЕТ serviceScope?.cancel() - корутины продолжают работать!
    // ...
}

Последствия:

  • ❌ Service Context остаётся в памяти через активные Job
  • ❌ ScriptEngine продолжает выполнять скрипт после destroy
  • ❌ Потенциальный крэш при обращении к уничтоженному Service
  • ❌ Постепенная утечка памяти при многократном запуске/остановке

🛠️ Исправление

FloatingWindowService.kt (onDestroy)

БЫЛО:

override fun onDestroy() {
    super.onDestroy()
    isDestroyed = true
    stopScript()
    handler.removeCallbacksAndMessages(null)
    // ... cleanup views
}

СТАЛО:

override fun onDestroy() {
    super.onDestroy()
    isDestroyed = true
    stopScript()
    
    // ✅ КРИТИЧНО: Отменяем корутины перед уничтожением сервиса
    scriptJob?.cancel()
    serviceScope?.cancel()
    serviceScope = null
    currentEngine = null
    
    handler.removeCallbacksAndMessages(null)
    // ... cleanup views
}

✅ Что исправлено

1. Корутины корректно отменяются

serviceScope?.cancel()  // Отменяет ВСЕ корутины в scope
scriptJob?.cancel()     // Дополнительная гарантия для текущего Job

2. Ссылки очищаются

serviceScope = null     // Удаляем ссылку на scope
currentEngine = null    // Предотвращаем использование после destroy

3. Правильный порядок cleanup

  1. stopScript() - корректная остановка через UI
  2. cancel() - принудительная отмена корутин
  3. Очистка Handler callbacks
  4. Удаление Views из WindowManager

🧪 Сценарии тестирования

До исправления (❌ Баг):

1. Запустить долгий скрипт (например, с loop 1000 раз)
2. Закрыть FloatingWindow через кнопку
3. Скрипт продолжает выполняться в фоне
4. Service Context остаётся в памяти
5. При повторении накапливается утечка

После исправления (✅ Работает):

1. Запустить долгий скрипт
2. Закрыть FloatingWindow
3. serviceScope.cancel() немедленно останавливает корутины
4. Context освобождается
5. Нет утечки памяти

📊 Влияние

Критичность: HIGH

  • Долгоживущий сервис с корутинами
  • Используется постоянно во время работы автокликера
  • Накопительная утечка при многократном запуске/остановке

Затронутые сценарии:

  • Закрытие FloatingWindow пользователем
  • Уничтожение сервиса системой (low memory)
  • Перезапуск сервиса
  • Переключение между скриптами

Производительность:

  • ✅ Немедленное освобождение памяти при onDestroy
  • ✅ Предотвращение накопления "зомби" корутин
  • ✅ Снижение нагрузки на GC

🎯 Изменённый файл

  • FloatingWindowService.kt (lines 575-590) - добавлен корректный cleanup корутин в onDestroy()

🔍 Анализ других Services

Проверены все остальные сервисы в проекте:

  • UpdateDownloadService - уже есть serviceScope.cancel() в onDestroy
  • ClickerAccessibilityService - не использует корутины
  • ScreenCaptureService - не использует корутины
  • ColorPickerService - правильный cleanup Handler
  • MacroRecorderService - правильный cleanup Handler
  • CoordinateOverlayService - минимальный сервис, cleanup в порядке

Вывод: Только FloatingWindowService имел эту критичную проблему! 🎯


Теперь сервис корректно освобождает ресурсы при уничтожении! 💧✨


💻 View my work • 👤 Initiated by @ARTEMKOPIKAbout Codegen
⛔ Remove Codegen from PR🚫 Ban action checks

ПРОБЛЕМА:
❌ serviceScope не очищался в onDestroy()
❌ При уничтожении сервиса во время выполнения скрипта корутины продолжали работать
❌ Service Context оставался в памяти через активные Job
❌ Потенциальный крэш при обращении к уничтоженному Service

ИСПРАВЛЕНИЕ:
✅ Добавлен serviceScope?.cancel() в onDestroy()
✅ Добавлен scriptJob?.cancel() для страховки
✅ serviceScope = null для гарантии очистки ссылки
✅ currentEngine = null для предотвращения использования после destroy

РЕЗУЛЬТАТ:
✅ Корутины корректно отменяются при уничтожении сервиса
✅ Нет memory leak через активные Job
✅ Нет крэшей при обращении к Context после onDestroy

Это критичный баг для долгоживущего сервиса! 🛡️

Co-authored-by: ARTEMKOPIK <[email protected]>
@ARTEMKOPIK ARTEMKOPIK merged commit 493f4e6 into main Dec 26, 2025
2 checks passed
@github-actions
Copy link
Contributor

✅ Build Status

Build success

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