Telegram Group & Telegram Channel
Почему ваша картинка размером в 2 мегабайта может отъедать 80 мб памяти? Сейчас разберёмся.
Или как пофиксить одну из причин out of memory exception

На собеседованиях часто просят отобразить ленту из картинок, взятых откуда-нибудь из стороннего ресурса, гугла, например, условного unsplash или откуда-нибудь ещё. Скорее всего, и у инженеров на боевых проектах рано или поздно может возникнуть подобная задача.

Одна из потенциальных сложностей, с которой можно столкнуться при такой задаче — out of memory exception. Так в чём же дело?

Использование памяти нашим приложением резко возрастает, когда мы начинаем показывать HD-изображения на экране (даже одно уже может внести существенный импакт для увеличения используемой памяти).

Главное, что нужно запомнить, использование памяти ≠ размеру файла. И вот почему.

Использование памяти связано с размерами изображения, а не с размером файла (Session 416, WWDC 2018).

Всё дело в том, что для отображения изображения на экране, iOS сначала необходимо декодировать и распаковать изображение. Обычно 1 пиксель декодированного изображения занимает 4 байта памяти — 1 байт для красного, 1 байт для зеленого, 1 байт для синего и 1 байт для альфа-канала (да-да, тот самый RGB с альфой). Например:

(3648 * 5472) * 4 bytes ≈ 80MB

И именно это значение и будет отображаться, когда мы будем чекать, что же происходит в приложении.

Что со всем этим делать?

Разработчики в этой статье пробовали менять масштаб и перерисовать изображение, но это не помогло. Это связано с тем, что операции для изменения размера для UIImage дороги. В процессе изменения размера iOS по-прежнему будет декодировать и распаковывать исходное изображение, вызывая нежелательный скачок памяти.

Одно из решений, которым делятся инженеры Apple — юзать даунсэмплинг.

Мы можем использовать ImageIO для изменения размера изображения перед его отображением на экране. По факту, для нас это выльется только в стоимости ресайзинга исходной картинки. Вот здесь можно чекнуть сниппет.

Флаги, которые можно использовать

1️⃣ kCGImageSourceShouldCache — когда для этого флага установлено значение false, мы сообщаем основному фреймворку, что нам нужно только создать ссылку на источник изображения и не хотим декодировать изображение сразу при создании объекта CGImageSource.

В ситуации, когда у вас нет доступа к пути к источнику изображения, вы можете создать объект CGImageSource, используя инициализатор CGImageSourceCreateWithData().

2️⃣ kCGImageSourceShouldCacheImmediately — этот флаг указывает, что декодировать изображение нужно именно в тот момент, когда мы запускаем процесс понижения дискретизации.

3️⃣ kCGImageSourceCreateThumbnailWithTransform — установка этого флага в значение true очень важно для сохранения исходной ориентации.

Подводные камни (а как же без них)

Имейте в виду, что даунсэмплинг — это процесс, который потребляет ресурсы процессора. Таким образом, по-прежнему предпочтительнее использовать правильно масштабированный источник изображения, а не понижать дискретизацию HD-изображения. Другими словами, вы должны использовать даунсэмплинг только тогда, когда вам нужно отобразить изображение, размер которого намного превышает требуемый размер на экране.

Важные моменты

Помните, что память — это конечный и общий ресурс.

Используйте встроенный в Xcode мониторинг.

Позвольте iOS выбрать ваши форматы изображений, когда это возможно.

Используйте ImageIO для понижения разрешения изображений (помните про подводные камни).

Выгружайте крупные ресурсы, которые находятся за пределами экрана.

Не игнорируйте графики памяти (memory graphs), чтобы лучше понять, что происходит.

Что почитать ещё?

📖 Deep Dive into iOS Memory.
📖 Reducing Memory Footprint When Using UIImage.
📺 Session 416, WWDC 2018.
🔗 https://developer.apple.com/documentation/imageio/cgimagesource.

@iOS Dev — отвечаем на вопросы.
🔥36👍13🏆62👏1



tg-me.com/iosdev/537
Create:
Last Update:

Почему ваша картинка размером в 2 мегабайта может отъедать 80 мб памяти? Сейчас разберёмся.
Или как пофиксить одну из причин out of memory exception

На собеседованиях часто просят отобразить ленту из картинок, взятых откуда-нибудь из стороннего ресурса, гугла, например, условного unsplash или откуда-нибудь ещё. Скорее всего, и у инженеров на боевых проектах рано или поздно может возникнуть подобная задача.

Одна из потенциальных сложностей, с которой можно столкнуться при такой задаче — out of memory exception. Так в чём же дело?

Использование памяти нашим приложением резко возрастает, когда мы начинаем показывать HD-изображения на экране (даже одно уже может внести существенный импакт для увеличения используемой памяти).

Главное, что нужно запомнить, использование памяти ≠ размеру файла. И вот почему.

Использование памяти связано с размерами изображения, а не с размером файла (Session 416, WWDC 2018).

Всё дело в том, что для отображения изображения на экране, iOS сначала необходимо декодировать и распаковать изображение. Обычно 1 пиксель декодированного изображения занимает 4 байта памяти — 1 байт для красного, 1 байт для зеленого, 1 байт для синего и 1 байт для альфа-канала (да-да, тот самый RGB с альфой). Например:

(3648 * 5472) * 4 bytes ≈ 80MB

И именно это значение и будет отображаться, когда мы будем чекать, что же происходит в приложении.

Что со всем этим делать?

Разработчики в этой статье пробовали менять масштаб и перерисовать изображение, но это не помогло. Это связано с тем, что операции для изменения размера для UIImage дороги. В процессе изменения размера iOS по-прежнему будет декодировать и распаковывать исходное изображение, вызывая нежелательный скачок памяти.

Одно из решений, которым делятся инженеры Apple — юзать даунсэмплинг.

Мы можем использовать ImageIO для изменения размера изображения перед его отображением на экране. По факту, для нас это выльется только в стоимости ресайзинга исходной картинки. Вот здесь можно чекнуть сниппет.

Флаги, которые можно использовать

1️⃣ kCGImageSourceShouldCache — когда для этого флага установлено значение false, мы сообщаем основному фреймворку, что нам нужно только создать ссылку на источник изображения и не хотим декодировать изображение сразу при создании объекта CGImageSource.

В ситуации, когда у вас нет доступа к пути к источнику изображения, вы можете создать объект CGImageSource, используя инициализатор CGImageSourceCreateWithData().

2️⃣ kCGImageSourceShouldCacheImmediately — этот флаг указывает, что декодировать изображение нужно именно в тот момент, когда мы запускаем процесс понижения дискретизации.

3️⃣ kCGImageSourceCreateThumbnailWithTransform — установка этого флага в значение true очень важно для сохранения исходной ориентации.

Подводные камни (а как же без них)

Имейте в виду, что даунсэмплинг — это процесс, который потребляет ресурсы процессора. Таким образом, по-прежнему предпочтительнее использовать правильно масштабированный источник изображения, а не понижать дискретизацию HD-изображения. Другими словами, вы должны использовать даунсэмплинг только тогда, когда вам нужно отобразить изображение, размер которого намного превышает требуемый размер на экране.

Важные моменты

Помните, что память — это конечный и общий ресурс.

Используйте встроенный в Xcode мониторинг.

Позвольте iOS выбрать ваши форматы изображений, когда это возможно.

Используйте ImageIO для понижения разрешения изображений (помните про подводные камни).

Выгружайте крупные ресурсы, которые находятся за пределами экрана.

Не игнорируйте графики памяти (memory graphs), чтобы лучше понять, что происходит.

Что почитать ещё?

📖 Deep Dive into iOS Memory.
📖 Reducing Memory Footprint When Using UIImage.
📺 Session 416, WWDC 2018.
🔗 https://developer.apple.com/documentation/imageio/cgimagesource.

@iOS Dev — отвечаем на вопросы.

BY iOS Dev




Share with your friend now:
tg-me.com/iosdev/537

View MORE
Open in Telegram


telegram Telegram | DID YOU KNOW?

Date: |

If riding a bucking bronco is your idea of fun, you’re going to love what the stock market has in store. Consider this past week’s ride a preview.The week’s action didn’t look like much, if you didn’t know better. The Dow Jones Industrial Average rose 213.12 points or 0.6%, while the S&P 500 advanced 0.5%, and the Nasdaq Composite ended little changed.

What is Secret Chats of Telegram

Secret Chats are one of the service’s additional security features; it allows messages to be sent with client-to-client encryption. This setup means that, unlike regular messages, these secret messages can only be accessed from the device’s that initiated and accepted the chat. Additionally, Telegram notes that secret chats leave no trace on the company’s services and offer a self-destruct timer.

telegram from us


Telegram iOS Dev
FROM USA