Подтвердить что ты не робот

Была ли конкретная причина сбора мусора не для C?

Я слышал, что было субоптимально для C автоматически собирать мусор - есть ли в этом правда?

Была ли определенная причина, что сбор мусора не был реализован для C?

4b9b3361

Ответ 1

Не слушайте "C старый и почему он не имеет GC". Существуют фундаментальные проблемы с GC, которые невозможно преодолеть, что делает его несовместимым с C.

Самая большая проблема заключается в том, что для точной сборки мусора требуется возможность сканирования памяти и выявления любых указателей. Некоторые языки более высокого уровня ограничивают целые числа, чтобы не использовать все доступные биты, так что высокие биты могут использоваться для выделения ссылок на объекты из целых чисел. Такие языки могут затем хранить строки (которые могут содержать произвольные последовательности октетов) в специальной зоне строк, где их нельзя путать с указателями, и все хорошо. Однако реализация C не может сделать этого, потому что байты, большие целые числа, указатели и все остальное могут храниться вместе в структурах, объединениях или как часть кусков, возвращаемых malloc.

Что делать, если вы выбрасываете требование точности и решаете, что вы в порядке с несколькими объектами, которые никогда не освобождаются, потому что некоторые данные без указателя в программе имеют тот же бит, что и адреса этих объектов? Теперь предположим, что ваша программа получает данные из внешнего мира (сеть/файлы/и т.д.). Я утверждаю, что могу сделать вашу программу утечкой произвольного объема памяти и в конечном итоге исчерпать память, если я могу догадаться о достаточном количестве указателей и эмулировать их в строках, которые я передаю вашей программе. Это становится намного проще, если вы примените De Bruijn Sequences.

Кроме того, сбор мусора просто медленный. Вы можете найти сотни ученых, которые любят заявлять об ином, но это не изменит реальности. Проблемы производительности GC можно разделить на 3 основные категории:

  • Непредсказуемость
  • Кэширование загрязнений
  • Время, потраченное на всю память.

Люди, которые будут требовать GC в наши дни, просто сравнивают это с неправильным: плохо написанные программы на C и С++, которые выделяют и освобождают тысячи или миллионы объектов в секунду. Да, они также будут медленными, но, по крайней мере, предсказуемо медленными темпами, которые вы можете измерить и исправить, если необходимо. Хорошо написанная программа на C проведет так мало времени в malloc/free, что накладные расходы даже не измеримы.

Ответ 2

Сбор мусора был реализован для C (например, сборщик Boehm-Demers-Weiser). C не был указан для включения GC, когда он был новым по ряду причин - во многом потому, что для оборудования, на которое они были нацелены, и системы, которую они строили, это просто не имело большого смысла.

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

  • Чтобы сделать консервативный GC определенным, вы в основном должны сделать только одно изменение языка: скажите, что все, что делает указатель временно "невидимым", приводит к поведению undefined. Например, в текущем C вы можете записать указатель в файл, перезаписать указатель в памяти, позже прочитать его обратно и (предположив, что он был ранее действителен) по-прежнему получать доступ к данным, на которые он указывает. GC не обязательно "понимал", что указатель существует, поэтому он мог видеть, что память больше не доступна и поэтому открыта для сбора, поэтому более поздняя развязка "не работает".

  • Поскольку сбор мусора является недетерминированным: существуют коллекторы реального времени, которые являются абсолютно детерминированными и могут использоваться в жестких системах реального времени. Существуют также детерминированные кучевые менеджеры для ручного управления, но большинство ручных менеджеров не являются детерминированными.

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

  • Что касается GC, работающего в неизвестные или неожиданные моменты времени: это не обязательно более или менее верно, чем при использовании управляемой вручную памяти. Вы можете запустить GC в отдельном потоке, который запускается (хотя бы несколько) непредсказуемо. То же самое верно для объединения свободных блоков с ручным управлением памятью. Конкретная попытка выделения памяти может инициировать цикл сбора, что приводит к тому, что некоторые распределения намного медленнее других; то же самое верно и с ручным менеджером, который использует ленивое объединение свободных блоков.

  • Как ни странно, GC гораздо менее совместим с С++, чем с C. Большинство С++ зависит от детерминированного вызова деструкторов, но с сборкой мусора, которая больше не имеет места. Это ломает много кода - и чем лучше написан код, тем больше проблема, которую он обычно вызывает.

  • Аналогично, С++ требует, чтобы std::less<T> обеспечивал значимые (и, что более важно, последовательные) результаты для указателей, даже если они указывают на полностью независимые объекты. Для выполнения этого требования потребуется дополнительная работа с копировальным коллектором/мусорщиком (но я уверен, что это возможно). Сложнее еще заняться (например), кто-то хеширует адрес и ожидает согласованных результатов. Это, как правило, плохая идея, но она по-прежнему возможна и должна давать согласованные результаты.

Ответ 3

C был изобретен еще в начале 1970-х годов для написания операционных систем и других низкоуровневых материалов. Собиратели мусора были вокруг (например, ранние версии Smalltalk), но я сомневаюсь, что они справились с задачей работать в такой легкой среде, и все сложности были бы осложнены работой с буферами и указателями низкого уровня.

Ответ 4

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

Запрашивая, почему C не имеет GC, но другие языки немного напоминают вопрос: "Почему у молотка есть тупой конец, когда топор имеет острый конец"? Ну, языки - это инструменты, а разные инструменты предназначены для создания разных программ с различными требованиями. Некоторые программы, такие как драйверы устройств или ядра операционной системы, имеют требования, из-за которых практически невозможно реализовать сборку мусора, все еще удовлетворяя их, поэтому необходим язык, такой как C, поэтому был создан C.

Как и любой другой инструмент, так оно и есть, потому что проблемы, которые он должен был решить, заставляли это быть таким. Люди, которые говорят, что это было потому, что он был создан в 70-х годах или из-за старого оборудования, похоже, что он был полностью косвенным. Если бы это было так, то C исчезло бы с 70-х годов, но это все еще популярный язык.

Кроме того, gc очень сложно реализовать без какой-либо системы времени исполнения, но C предназначен для работы на голом оборудовании.

Ответ 5

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

Добавление автоматической сборки мусора на язык обычно будет либо снижать производительность, либо приведет к тому, что сбор мусора произойдет в unsesese times. Чтобы добавить сборку мусора в C, это приведет к потере ее одного из сравнительных преимуществ, поскольку она может использоваться для программирования на системном уровне, требующего времени реального времени или близкого к реальному времени отклика.

Ответ 6

Как язык, C был намеренно разработан, чтобы быть действительно маленьким. У него очень мало встроенных операций или функций, и большинство из них отражает основные инструкции, найденные в CPU. Его часто называли "переносным языком ассемблера".

Это отлично подходит для написания переносных программ для переключения телефонных звонков, которые работают на маленьких маленьких компьютерах с очень маленькой памятью, что является частью того, что Bell Labs было в начале 70-х, когда они впервые работали над C и Unix.

Это также отлично подходит для написания ядер ОС, драйверов устройств и т.д. Такие исполняемые файлы не могут рассчитывать на наличие богатых, сложных сред выполнения, таких как сбор мусора, или даже просто динамическое распределение памяти, например malloc(). Это потому, что они на самом деле составляют основу для этих сред, поэтому вы сталкиваетесь с проблемой "потянув себя за свои бутстрапы".

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

Ответ 7

C - язык очень низкого уровня. Это тот язык, на котором вы могли бы написать язык более высокого уровня с такими вещами, как сбор мусора. Он маленький и простой, и делает именно то, что вы просите.

Требуется, чтобы С++ построил на C и добавил более сложное/автоматическое управление памятью (такие вещи, как вызов деструкторов, когда объекты выходили из сферы действия). Вы можете тогда задаться вопросом, почему С++ не содержит сборку мусора, и в этом случае посмотрите, что говорит Stroustrup : вкратце, люди хотят делать вещи в более прямой способ, и люди, которые действительно хотят этого, могут использовать библиотеку (которая также может быть использована в C).

Ответ 8

Objective_C - это ANSI C с добавлением 12 ключевых слов и типа с именем id. У него есть сбор мусора. Он использует подсчет ссылок.

Ответ 9

Мне нравится, что JWZ говорит о C.: -)

C является "ассемблером PDP-11, который считает его языком".

Итак, если вы посмотрите, как вы создадите переносимый ассемблер, тогда C выглядит совершенно без мусора, по той простой причине, что у процессоров нет команды "сбор мусора". *

(В то время как большинство других инструкций CPU с сегодняшнего дня фиксируются только с C, некоторые из них не такие, как отсутствие у Cs выразительности для операций SIMD и т.д.)

* Да, я знаю, что некоторые из вас найдут пример, чтобы доказать, что я ошибаюсь. Но в общем случае...

Ответ 10

Сбор мусора может быть реализован для C, хотя с обычным аппаратным обеспечением процессора это будет несколько сложно и неэффективно. Чтобы действительно сделать сборку мусора хорошо, нужна архитектура, которая использовала базовую + смещенную адресацию для всего; базовая часть каждого указателя должна всегда указывать на начало выделенной области. Обратите внимание: если база была "селектором", а не линейным адресом, 32-разрядный селектор плюс 32-битное смещение могли бы получить доступ к 4 миллиардам объектов, каждый из которых мог бы составлять до 4 концертов. Я бы подумал, что такой дизайн может быть более эффективным, чем 64-разрядная линейная адресация для многих приложений, поскольку ссылки на объекты и смещения будут использовать вдвое меньше кэширования, чем для 64-битных указателей. Использование 64 бит просто похоже на отходы.

BTW, архитектура, которая использовала базовый + смещенный адрес для всего, имела бы еще одно преимущество перед системой линейной адресации: сбор мусора может запускаться одновременно с другими операциями. Единственный раз, когда сбор мусора должен был нарушить выполняемый поток, было бы, если бы поток попытался получить доступ к объекту данных, когда этот конкретный объект был перемещен. В этом случае попытка перемещения должна быть прервана (предполагается, что это неперекрывающаяся копия), или потоку придется ждать, пока этот конкретный объект будет скопирован. Гораздо лучшая ситуация для кода в реальном времени, чем существует, когда все потоки должны быть приостановлены для GC.

Ответ 11

Сила (и слабость) C состоит в том, что она небольшая, простая, легкая и хорошо подходит для встроенных и системных приложений. GC добавит накладные расходы, и это будет уже не так просто и просто. GC для C просто не подходит. Это не сложнее, чем это.

Ответ 12

1972.

C был разработан в 1972 году.

Хуже того, c был разработан на устаревшем оборудовании. В 1972 году.

Не поймите меня неправильно. У них была сборка мусора в 1972 году, но все проблемы, которые люди жалуются по сей день, были реальной, очень актуальной проблемой в то время.

Ответ 13

Сбор мусора не полезен, если вы хотите сделать хардкорную оптимизацию, потому что, если вы решите момент, когда лучше всего освободить выделенное пространство, то вы можете сделать намного лучшую работу в своем проекте, чем сборщик мусора. В 1970-е годы я не знаю точной причины, по которой разработчики решили не включать сборщика мусора в C, возможно, они хотели иметь абсолютный контроль за освобождением, однако я уверен, что позже они даже не подумали добавить мусор коллекционер, потому что, даже если есть интеграция сборщика мусора на язык, который очень хорош, было построено много проектов C, и новые версии языка должны иметь обратную совместимость.

EDIT: "Существуют также компиляторы, библиотеки и механизмы уровня операционной системы для выполнения проверки границ массивов, обнаружения переполнения буфера, сериализации и автоматического сбора мусора, которые не являются стандартной частью C.". Это может быть интересно для вас, вы можете прочитать здесь здесь.