Как выгрузить объект из памяти, когда он перестал быть необходим, при использовании Addressables для загрузки?
Комментарии (2)
Ответ сгенерирован нейросетью и может содержать ошибки
Управление памятью при работе с Addressables
При использовании Addressables System в Unity выгрузка объектов из памяти происходит иначе, чем при традиционном подходе с Resources.UnloadUnusedAssets(). Addressables предоставляет более контролируемый и предсказуемый механизм управления памятью, основанный на явном освобождении ссылок.
Ключевые механизмы выгрузки
Основные способы выгрузки объектов, загруженных через Addressables:
- Release Instance - для экземпляров игровых объектов
- Release Asset - для загруженных ассетов
- Auto-release через Reference Counting - автоматическое управление через подсчет ссылок
Практическая реализация
1. Выгрузка экземпляров GameObject
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.ResourceManagement.AsyncOperations;
public class AddressableManager : MonoBehaviour
{
private AsyncOperationHandle<GameObject> _handle;
private GameObject _loadedObject;
async void Start()
{
// Загрузка объекта
_handle = Addressables.LoadAssetAsync<GameObject>("MyPrefab");
_loadedObject = await _handle.Task;
// Создание экземпляра
GameObject instance = Instantiate(_loadedObject);
// Когда объект больше не нужен
Destroy(instance);
// Важно: освобождаем handle, а не только уничтожаем GameObject
Addressables.Release(_handle);
}
}
2. Работа с Reference Counting
Addressables использует систему подсчета ссылок. Каждый вызов LoadAssetAsync увеличивает счетчик, а Release - уменьшает. Объект выгружается, когда счетчик достигает нуля.
public class AssetLoader : MonoBehaviour
{
private List<AsyncOperationHandle> _handles = new List<AsyncOperationHandle>();
public async void LoadAndReleaseMultiple()
{
// Загрузка нескольких ассетов
var handle1 = Addressables.LoadAssetAsync<Texture>("Texture1");
var handle2 = Addressables.LoadAssetAsync<Material>("Material1");
_handles.Add(handle1);
_handles.Add(handle2);
await Task.WhenAll(handle1.Task, handle2.Task);
// Использование ассетов...
// Выгрузка всех ассетов
foreach (var handle in _handles)
{
Addressables.Release(handle);
}
_handles.Clear();
}
}
3. Автоматическое управление через using-паттерн
public async Task<TemporaryAssetUsage> TemporaryLoadAsset()
{
var handle = Addressables.LoadAssetAsync<GameObject>("TemporaryAsset");
await handle.Task;
// Используем using для автоматического освобождения
return new TemporaryAssetUsage(handle);
}
public class TemporaryAssetUsage : System.IDisposable
{
private AsyncOperationHandle<GameObject> _handle;
public TemporaryAssetUsage(AsyncOperationHandle<GameObject> handle)
{
_handle = handle;
}
public void Dispose()
{
Addressables.Release(_handle);
}
}
Важные аспекты и рекомендации
Проблемы и решения:
-
Утечки памяти: Часто возникают, когда разработчики забывают вызвать
Release(). Всегда отслеживайте ваши handles -
Статистика и мониторинг:
// Проверка использования Addressables
Debug.Log($"Total Handles: {Addressables.ResourceManager.ActiveHandlesCount}");
- Категории выгрузки:
- Manual Release: Полный контроль, но требует внимательности
- Scene-based Release: Автоматическая выгрузка при смене сцены
- Time-based Release: Выгрузка через определенное время неактивности
Оптимизация стратегий:
-
Группировка ресурсов: Объединяйте связанные ассеты в один AssetBundle для одновременной загрузки/выгрузки
-
Приоритеты выгрузки: Критичные ресурсы оставляйте в памяти, временные - быстро выгружайте
-
Профилирование: Используйте Addressables Event Viewer и Memory Profiler для отслеживания использования
Распространенные ошибки
- Двойное освобождение: Вызов
Release()несколько раз для одного handle - Несоответствие типов: Загрузка одного типа, а освобождение другого
- Утечка в корутинах: Незавершенные асинхронные операции, которые сохраняют ссылки
Передовые практики
- Всегда используйте await/async вместо callback-ов для лучшей читаемости
- Создайте фасад или менеджер для централизованного управления Addressables
- Реализуйте паттерн Object Pool для часто используемых объектов
- Используйте Addressables Analyze Tool для проверки целостности ссылок
Addressables System обеспечивает мощный механизм управления памятью, но требует дисциплинированного подхода к освобождению ресурсов. Ключевой принцип: "что явно загружено через Addressables, должно быть явно освобождено через Release()".