Почему это создает утечку памяти (iPhone)?

Это - второй случай - связан с не очень известным параметром «hive.fetch.task.conversion» .

В зависимости от того, как установлено, Hive может запустить одну «задачу извлечения» вместо задания «Уменьшить карту» даже с фильтром, т.е. предложением where.

Если вы выберете * или неразмеченный столбец, он запустит задачу извлечения вместо MR-job - одиночный поток. Отдельная тема не всегда хорошая вещь. Счетчик (*) должен говорить сам за себя, потенциально вам нужно много обработать, второй случай можно рассматривать как курсор.

Вы можете изменить параметр на «минимальный» или «нет» в hive-site.xml, чтобы устранить этот тип обработки.

Хорошо заметили.

8
задан Almas Adilbek 9 July 2012 в 10:25
поделиться

6 ответов

Корректное поведение зависит от объявления editMyObject @property. Принятие это объявляется как

@property (retain) id editMyObject; //id may be replaced by a more specific type

или

@property (copy) id editMyObject;

затем присвоение через self.editMyObject = сохраняет или копирует назначенный объект. С тех пор [[MyObject alloc] init] возвращает сохраненный объект, что Вы как собственная вызывающая сторона, у Вас есть дополнительное, сохраняют экземпляра MyObject, и он поэтому протечет, если это там не будет выпуск соответствия (как во втором блоке). Я предположил бы, что Вы читаете Руководство по программированию управления памятью [2].

Ваш второй блок кода корректен, предполагая, что свойство объявляется, как описано выше.

p.s. Вы не должны использовать [self.editMyObject release] в a -dealloc метод. Необходимо звонить [editMyObject release] (принятие ivar поддержка @property называют editMyObject). Вызов средства доступа (через self.editMyObject безопасно для @synthesized средств доступа, но если переопределенное средство доступа полагается на объектное состояние (который не может быть допустимым в призывающем местоположение -dealloc или вызывает другие побочные эффекты, у Вас есть ошибка путем вызова средства доступа.

[2] Правила монопольного использования объекта в Какао очень просты: если Вы называете метод, который имеет alloc, или copy в его подписи (или использование +[NSObject new] который в основном эквивалентен [[NSObject alloc] init]), затем Вы "владеете" объектом, который возвращается, и необходимо сбалансировать приобретение владения с a release. Во всех других случаях Вы не владеете объектом, возвращенным из метода. Если Вы хотите сохранить его, необходимо взять владение с a retain, и более позднее владение выпуска с a release.

10
ответ дан 5 December 2019 в 06:24
поделиться

Ваше свойство объявляется, "сохраняют" подразумевать, что оно переданный в объекте автоматически сохраняется.

Поскольку Ваш объект уже имел подсчет ссылок одного от alloc/init существует затем две ссылки, и я принимаю только один выпуск (в Вашем деструкторе).

В основном вызов к self.editMyObject действительно делает это;

-(void) setEditMyObject:(MyObject*)obj
{
  if (editMyObject)
  {
    [editMyObject release];
    editMyObject = nil;
  }

  editMyObject = [obj retain];
}
8
ответ дан 5 December 2019 в 06:24
поделиться

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

self.editMyObject = [[[MyObject alloc] init] autorelease];

Это оставит Ваш (сохранять) свойство как единственного владельца нового объекта. Точно тот же результат как Ваш второй пример, но без временного объекта.

1
ответ дан 5 December 2019 в 06:24
поделиться

Условно в Какао и касании Какао, любой объект создал использование [[SomeClass alloc] initX] или [SomeClass newX] создается с сохранить количеством одного. Вы ответственны за вызов [someClassInstance release] когда Вы сделаны с Вашим новым экземпляром, обычно в Вашем dealloc метод.

То, где это становится хитрым, - когда Вы присваиваете свой новый объект свойству вместо переменной экземпляра. Большинство свойств определяется как retain или copy, что означает, что они или увеличивают объект, сохраняют количество, когда установлено или делают копию объекта, оставляя оригинал нетронутым.

В Вашем примере у Вас, вероятно, есть это в Вашем .h файл:

@property (retain) MyObject *editMyObject;

Таким образом в Вашем первом примере:

// (2) property setter increments retain count to 2
self.editMyObject = 

    // (1) new object created with retain count of 1
    [[MyObject alloc] init];

// oops! retain count is now 2

Когда Вы создаете свой новый экземпляр MyObject использование alloc/init, это имеет сохранить количество одного. Когда Вы присваиваете новый экземпляр self.editMyObject, Вы на самом деле звоните -setEditMyObject: метод, который компилятор создает для Вас когда Вы @synthesize editMyObject. Когда компилятор видит self.editMyObject = x, это заменяет его [self setEditMyObject: x].

В Вашем втором примере:

MyObject *temp = [[MyObject alloc] init];
// (1) new object created with retain count of 1

self.editMyObject = temp;
// (2) equivalent to [self setEditMyObject: temp];
// increments retain count to 2

[temp release];
// (3) decrements retain count to 1

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

См. также стратегию Какао указателя/управления памятью

4
ответ дан 5 December 2019 в 06:24
поделиться

Первая версия создает объект без выпуска соответствия. Когда Вы выделение объект, это означает, что Вы - владелец того объекта. Ваш метод set, по-видимому, сохраняет объект (поскольку он должен), означая, что Вы теперь владеете объектом дважды. Вам нужен выпуск для балансировки создания объекта.

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

3
ответ дан 5 December 2019 в 06:24
поделиться

It was agreed and explained that the code below does not have a leak (assuming @property retain and @synthesize for editMyObject) :

//does not create memory leak
MyObject *temp = [[MyObject alloc] init];
self.editMyObject = tempt;
[temp release];

Question : is anything wrong with the following code that does not use a temp pointer ?

//does not create memory leak ?
self.editMyObject = [[MyObject alloc] init];
[editMyObject release];

To me this looks ok.

0
ответ дан 5 December 2019 в 06:24
поделиться