Im Stumped, почему память UIImage \ Texture2d не освобождается

Я везде искал, пытаясь найти решение этой проблемы. Кажется, ничего не помогает.

Я установил этот базовый тест, чтобы попытаться найти причину, по которой моя память не освобождалась:

if (texture != nil)
{
[texture release];
texture = nil;
}
else
{
UIImage* ui = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"image" ofType:@"png"]];
texture = [[Texture2D alloc] initWithImage:ui];
}

Теперь я бы поместил это в начальные касания и протестировал, отслеживая использование памяти с помощью инструментов в начале (обычно 11,5 - 12 МБ) после первого прикосновения, при отсутствии существующего объекта текстура создается и память перескакивает на 13,5 - 14

Однако после второго касания память действительно уменьшается, но только примерно до 12,5-13.

Заметный кусок памяти все еще занят.

Я тестировал это в гораздо большем масштабе, загружая по 10 таких больших текстур за раз. Объем памяти подскакивает до 30 МБ и остается там, но при втором касании после освобождения текстур она падает только примерно до 22 МБ.

Я попробовал этот тест в другой раз, загружая изображения с помощью [uiimage imagenamed:], но из-за кеширования, выполняемого этим методом, это означает, что в памяти остаются полные 30 МБ.


person user331951    schedule 04.05.2010    source источник


Ответы (2)


В вашем коде есть только одно место (из того, что мы видим), где текстура может быть освобождена, и это в операторе [texture release];.

Вам необходимо выполнить этот оператор (или еще один в другом месте). Вы проверяли, что для каждой выделенной текстуры вы также ее освобождаете? Вы можете добавить в помощь операторы NSLog, например:

if (texture != nil) {
    NSLog("releasing texture instance: %08x", texture);
    [texture release];
    texture = nil;
} else {
    ...
    texture = [[Texture2D alloc] initWithImage:ui];
    NSLog("allocated texture instance: %08x", texture);
}

Возможно, текстура сохраняется где-то еще? Например, вы добавляете его в подпредставление, в массив или словарь? Они сохраняют свое содержимое.

В крайнем случае, для решения действительно сложной проблемы отслеживания выделения / выпуска я переопределил методы сохранения, выпуска и освобождения, чтобы убедиться, что они вызываются тогда, когда я ожидаю. На данный момент это может быть излишним, но вот как: я добавил int myRetainCount; ivar, чтобы отслеживать:

-(void)release {
    NSLog(@"release %08x %2d -> %2d (%u)", 
          self, myRetainCount, myRetainCount-1, self.retainCount);
    myRetainCount--;
    [super release];
}

-(id)retain {
    NSLog(@"retain  %08x %2d -> %2d (%u)", 
          self, myRetainCount, myRetainCount+1, self.retainCount);
    myRetainCount++;
    return [super retain];
}

- (void)dealloc {
    NSLog(@"dealloc %08x %2d       (%u)", self, myRetainCount, self.retainCount);

    // deallocate self's ivars here...

    [super dealloc];
}
person progrmr    schedule 04.05.2010
comment
Спасибо за ваше время и такой быстрый ответ :). Для этого теста единственное место, где на эту текстуру когда-либо ссылаются (кроме объявления интерфейса), - это код, который я опубликовал. Я отчаянно нуждаюсь в объяснении, и я могу просто попробовать те переопределения, которые вы предложили. Однако я думаю, что проблема в другом, чего я не знаю. Может быть, что-то конкретное для Texture2D, или того, как iPhone обрабатывает память, или самих инструментов. Используя отладчик, я показал, что были вызваны методы освобождения от текстуры для texture2d. - person user331951; 04.05.2010

Кажется, я нашел проблему. Я не совсем знаю, почему это происходит, но кажется, что когда я запускаю инструменты для мониторинга использования памяти, если я одновременно отслеживаю активность ввода-вывода (это инструмент по умолчанию, который изначально загружается), показанное использование памяти НАМНОГО больше (более чем в 3 раза) и остается в памяти даже после освобождения объектов. Я предполагаю, что это из-за накладных расходов на мониторинг активности ввода-вывода.

В любом случае, когда я выключаю это значение, использование памяти изначально составляет 3,16 МБ (намного лучше) и перескакивает до 10 МБ при загрузке 10 огромных текстур и сразу же возвращается к 3,16 после того, как я выгрузил текстуру. Блестящий результат.

person user331951    schedule 04.05.2010