
- Главная
- Каталог
- Интернет технологии
- Программирование
Программирование
Статьи о программировании, обучающие видео IT, книги.
Статистика канала
this: Как одна лямбда может утечь всю Activity
Мы привыкли считать, что Kotlin умнее Java. В Java анонимный класс всегда держал ссылку на внешний класс. В Kotlin компилятор пытается оптимизировать лямбды и делать их статическими синглтонами.
Но эта магия ломается от одного прикосновения.
Представьте код во ViewModel или Presenter:
class HeavyScreen {
private val bigData = ByteArray(1024 * 1024 * 20) // 20 MB
private val title = "Profile"
fun load() {
ExternalService.fetchData { result ->
// (1) Просто логируем результат
println("Got result: $result")
// (2) А теперь раскомментируйте эту строку:
// println("Update for $title: $result")
}
}
}
{}
Разбор полетов:
1. Сценарий (1): Вы не обращаетесь к свойствам HeavyScreen внутри лямбды.
Kotlin компилирует эту лямбду как static instance. Ссылки на HeavyScreen нет. Если экран закроется, GC спокойно его соберет, даже если ExternalService будет грузить данные еще 10 минут.
2. Сценарий (2): Вы добавили обращение к title.
Всё. Оптимизация отключена.
Чтобы прочитать title, лямбде нужна ссылка на инстанс HeavyScreen. Компилятор скрыто передает this в конструктор лямбды.
Цепочка утечки:
ExternalService (static/singleton) -> Lambda -> this$0 (HeavyScreen) -> bigData (20 MB).
Пока ExternalService держит коллбэк - ваши 20 Мб висят в памяти, даже если пользователь давно ушел с экрана.
Как проверить себя?
Если вы передаете лямбду в объект, который живет дольше, чем ваш класс (Network Client, Singleton, Event Bus, Handler):
1. Убедитесь, что вы отписываетесь (clear references).
2. Или не захватывайте контекст (this) внутри лямбды (используйте только аргументы лямбды).
3. Используйте WeakReference, если архитектура позволяет (но это костыль).
Совет: В IntelliJ IDEA/Android Studio включите подсветку "Implicit usage of 'this'". Это спасет вам гигабайты RAM.
if (ветвление).
Процессор не знает, пойдет код в then или в else, пока не вычислит условие. Но ждать он не может - конвейер встанет. Поэтому он угадывает.
• Угадал? Выполнение продолжается без задержек.
• Не угадал? Происходит Pipeline Flush. Процессор выбрасывает все инструкции, которые успел "набрать" по неверному пути, и начинает заново с правильного адреса. Это огромная потеря тактов (10-20 циклов CPU).
Пример на Rust:
// Если data отсортирован: T T T T T F F F F F (паттерн ясен)
// Если data случайный: T F T T F F T F (паттерн непредсказуем)
for &x in &data {
if x > 128 {
sum += x;
}
}
{}
На случайных данных BPU ошибается в 50% случаев. На сортированных почти никогда.
Вывод: Чем предсказуемее ваши данные, тем быстрее работает ваш код. Иногда data.sort() перед обработкой окупается с лихвой.
#rust
list для любых задач, связанных с хранением последовательностей. Но что, если вам нужно эффективно добавлять или удалять элементы с обоих концов структуры?
Здесь на сцену выходит collections.deque (double-ended queue).
🚀 Почему Deque круче списка в определенных задачах?
Главная проблема list в том, что он оптимизирован для операций с правой стороны. Удаление или вставка в начало списка (list.insert(0, v) или list.pop(0)) заставляет Python сдвигать все остальные элементы, что дает сложность .
deque обеспечивает:
🔹O(1) для операций добавления/удаления как слева, так и справа.
🔹Возможность создания кольцевых буферов (ограниченных очередей).
🔹Потокобезопасность для атомарных операций добавления/удаления.
🛠 Примеры использования
from collections import deque
# 1. Создаем дек
d = deque(['middle'])
# 2. Добавляем элементы с двух сторон
d.append('right') # в конец
d.appendleft('left') # в начало
print(d) # deque(['left', 'middle', 'right'])
# 3. Удаляем элементы
d.pop()
d.popleft()
# 4. Ограниченная очередь (самое полезное!)
# Хранит только последние 3 элемента. Идеально для логов или истории.
history = deque(maxlen=3)
for i in range(5):
history.append(f"Action {i}")
print(history)
# Результат: всегда только последние 3 действия
{}
💡 Когда стоит использовать deque?
🔹Реализация очередей (FIFO) и стеков (LIFO).
🔹Алгоритмы обхода графов (BFS - поиск в ширину).
🔹Хранение последних логов или сообщений.
Важный нюанс: Доступ к элементам по индексу в середине дека (d[n]) работает медленнее (O(n)), чем в списке (O(1)). Если вам нужен частый произвольный доступ - оставайтесь на list.📖 Подробнее в статье: https://realpython.com/python-deque/ #python #backend
Отзывы канала
всего 10 отзывов
- Добавлен: Сначала новые
- Добавлен: Сначала старые
- Оценка: По убыванию
- Оценка: По возрастанию
Каталог Телеграм-каналов для нативных размещений
Программирование — это Telegam канал в категории «Интернет технологии», который предлагает эффективные форматы для размещения рекламных постов в Телеграмме. Количество подписчиков канала в 4.3K и качественный контент помогают брендам привлекать внимание аудитории и увеличивать охват. Рейтинг канала составляет 36.8, количество отзывов – 10, со средней оценкой 5.0.
Вы можете запустить рекламную кампанию через сервис Telega.in, выбрав удобный формат размещения. Платформа обеспечивает прозрачные условия сотрудничества и предоставляет детальную аналитику. Стоимость размещения составляет 1958.04 ₽, а за 25 выполненных заявок канал зарекомендовал себя как надежный партнер для рекламы в TG. Размещайте интеграции уже сегодня и привлекайте новых клиентов вместе с Telega.in!
Вы снова сможете добавить каналы в корзину из каталога
Комментарий