Управление памятью - C # VS Цель C? - PullRequest
4 голосов
/ 09 сентября 2010

ТАК Я уже знаю об управлении памятью в цели C, и мне никогда не приходилось знать об этом при программировании в .net (C #). Но у меня все еще есть вопросы о том, как все делается.

-Почему код просачивается в цель c, если мы выделяем объект, а не освобождаем его?

-Почему эта утечка в C # не возникает?

-Каковы преимущества и недостатки автоматического сбора мусора?

-Почему не использовать autorelease для каждого выделенного объекта (Цель C)?

-Можно ли позаботиться о памяти вручную (C #)? скажем, я создаю экземпляр объекта, и когда я закончу, я хочу освободить его, и я не хочу ждать, пока сборщик мусора сделает это?

Ответы [ 3 ]

8 голосов
/ 09 сентября 2010
  • Он просачивается в Objective-C, потому что Objective-C не предпринимает никаких действий с ним.Это зависит от того, как вы делаете всю работу.Он не протекает в C # (точнее, в .NET), потому что использует сборщик мусора , который очищает объекты, которые больше не используются.

  • Основное преимущество сборки мусора заключается в следующем: у вас гораздо меньше утечек памяти.(По-прежнему возможна утечка памяти, например, при бесконечном заполнении списка, но это сделать сложнее случайно.) Раньше считалось, что сборка мусора имеет недостаток в том, что она может замедлить работу программы, поскольку она продолжает выполнять сборку мусора.Коллекция в фоновом режиме, и вы имеете небольшой контроль над ней.В действительности, однако, разница незначительна: на вашем компьютере постоянно выполняются другие фоновые задачи (например, драйверы устройств), сборщик мусора также не ломает спину верблюда.

  • Автоматическое освобождение (поскольку оно используется в C ++, когда переменная без указателя выходит из области видимости) опасно, поскольку открывает возможность иметь ссылку на нее, существующую даже после удаления объекта.Если ваш код затем пытается получить доступ к объекту, процесс идет очень долго.

  • Да, можно сказать C # освободить память, вызвав сборщик мусора напрямую (GC.Collect()).Однако мне еще предстоит увидеть случай, когда это вообще необходимо.Если у вас фактически не хватает памяти, сборщик мусора уже включится автоматически и освободит столько, сколько сможет.

5 голосов
/ 09 сентября 2010

Objective-C не является языком для сбора мусора, поэтому у него нет возможности узнать, что объект больше не будет использоваться, если вы не скажете это.В этом и заключается цель сборщика мусора .NET: он проверяет, какие объекты больше не могут использоваться программой, и - в какой-то момент - избавляется от них, чтобы освободить память.Нет никаких гарантий относительно того, когда или если это когда-либо освободит любой данный оставленный объект;он просто пытается не использовать управление памятью.

C # не может освободить объект без сборщика мусора.Если вы отпустите объект, на который все еще ссылаются, ваша программа потерпит крах, когда вы попытаетесь использовать это.Это всегда риск ручного управления памятью, но, как и все «языки с управлением памятью», он пытается помешать вам совершить именно эту ошибку.Если вы хотите явно закрыть операцию объекта, реализуйте интерфейс ID, доступный для типа этого объекта, и используйте метод Dispose () для этого объекта - по сути, деструктор.Разумеется, убедитесь, что вы покончили с этим, и что объект будет вести себя правильно (создавая исключения), если что-то попытается использовать его после того, как это было выполнено Dispose () d of.

Objective-C является ссылкой-counted.Когда у объекта нет ссылок, он удаляет себя.Это не плохое решение "кто-то еще использует этот объект?"проблема, за исключением структур данных, которые ссылаются на себя;Круговые структуры данных будут висеть вечно, если с ними не будут обращаться аккуратно..NET не является счетчиком ссылок, поэтому он избавится от циклических структур данных, которые не могут быть достигнуты при выполнении кода.

Авторелиз - это просто «выпуск позже», для возврата значения, которое должно само- уничтожить, если код, который захватывает его, не хочет сразу его удерживать, насколько я понимаю.(Я не программист Objective-C, хотя.) Это обходит "кто выпускает этот объект?"проблема для вызовов, которые возвращают объект, не уничтожая его до завершения функции.Однако это особый вариант использования, и в большинстве других случаев он не имеет смысла.

4 голосов
/ 09 сентября 2010

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

В C # есть другие механизмы для освобождения других ресурсов, таких как файлы или соединения с БД, которые должны быть освобождены без ограничений. Например, using позволяет вам точно убедиться, что IDispose вызывается для объекта.

Системы с сборкой мусора, как правило, используют больше памяти в любой момент времени, чем хорошо настроенная ручная реализация. Конечно, у вас нет утечек памяти.

Качество и производительность сборщиков мусора могут сильно различаться, и это то, что вы не можете контролировать. Например, при работе GC может быть заметная задержка. В .NET вы можете позвонить GC.Collect(), чтобы сообщить GC, что сейчас будет хорошее время, но он может или не может слушать.

В наши дни Objective-C также собирает мусор на Mac. На iPhone это подсчитано, хотя, я полагаю, именно здесь вы столкнулись с проблемой.

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

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

РЕДАКТИРОВАТЬ: Полагаю, я не сказал этого явно - вы не можете вручную управлять выделением памяти в C #.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...