суббота, ноября 03, 2007

C++0x - сборка мусора и потоки

Герб Саттер пишет, что опциональная автоматическая сборка мусора не будет добавлена в новый стандарт языка. Однако, будут убраны вещи, которые ей препятствуют.
For C++0x, we're not going to add explicit support for garbage collection, and only intend to find ways to remove blocking issues like pointer hiding that make it difficult to add garbage collection in a C++ implementation.

Насколько я понимаю, это означает следующее. Разработчики компиляторов могут таки добавить автоматическую сборку мусора. А могут и не добавлять. И никаких гарантий по поводу этой сборки они предоставлять не обязаны. Получается кто в лес, кто по дрова. Собственно уже сейчас есть решения по автоматической сборке мусора в С++...

С потоками у них тоже не все ладится, но все же в каком-то виде они будут.

Более того, они не укладываются в расписание и не факт, что это будет C++09.

:-(

43 коммент.:

Sectoid комментирует...

И хорошо. GC есть мозг.

CyberZX комментирует...

Нафиг нафиг эту сборку в С++.
Не плодите мусор, сборка и не понадобится.

migmit комментирует...

Блин. Даже на полшага не могут подвести цепепе к нормальному состоянию.

Arseny Kapoulkine комментирует...

migmit, к сожалению, это нормально.
Нельзя сделать что-то кардинально лучше, не сломав предварительно это что-то.
Между тем, сила С++ - в огромном количестве уже написанного кода, поэтому ни одно из изменений в новом стандарте не будет ломать старый код. Засчет этого им очень сложно добавлять действительно важные фичи и исправлять действительно важные огрехи. Вот и получается такая ерунда, как С++0х.

archimed7592 комментирует...

Sectoid said...

И хорошо. GC есть мозг.



CyberZX said...

Нафиг нафиг эту сборку в С++.
Не плодите мусор, сборка и не понадобится.


Мне кажется, господа, что вы слишком уж категоричны. Ручная сборка нужна лишь там где она действительно необходима(учитывая как её преимущества, так и недостатки)... В остальных случаях(котрых 80% - вспоминаем Мейрса) автоматическая сборка мне не кажется таким уж излишеством.

CyberZX комментирует...

Понимаете, есть огромное количество высокуровневых языков со сборкой мусора. Тот же Java или C#. Так вот и используйте их.
Сила С++ это в хорошем компромиссе низкоуровневости и высокоуровневости, который не предлагает ни один из других языков.
Введение таких кардинальных изменений как GC очень сильно сдвинет этот баланс. И мы получим очередной гибрид Java/C#.

archimed7592 комментирует...

Понимаете, есть огромное количество высокуровневых языков со сборкой мусора. Тот же Java или C#. Так вот и используйте их.
Мне кажется, что я не спрашивал что мне использовать или не использовать.
Мне показалось, что вы с Sectoid считаете нецелесообразным введение в С++ GC. Предлагаю о целесообразности и поговорить, а не раздавать советы что и кому использовать.

Сила С++ это в хорошем компромиссе низкоуровневости и высокоуровневости, который не предлагает ни один из других языков.
Сила С++ в zero-overhead principle(D&E, Stroustrup). Не нужен тебе GC - не используй и будет тебе низкий уровень и полноценный ручной контроль.
К примеру некоторых не устраивают исключения ибо "они тормозят"(это не моё мнение и отстаивать я его не собираюсь) - вот они и пишут себе код, не использующий исключений, и не испытавают никаких проблем, а также не просят убрать механизм исключений из языка.

Введение таких кардинальных изменений как GC очень сильно сдвинет этот баланс. И мы получим очередной гибрид Java/C#.
Можно поинтересоваться, почему ты так считаешь? В Java/.NET/и т.п. нет никакого выбора и GC навязывается языком. К слову, даже если в С++ и введут GC, то он будет опциональным(и будет работать только там где ты ему скажешь), чего о Java/.NET я сказать не могу.
Только лишь примеру ради: в managed C++ есть выбор - использовать new или gcnew, но там new только для одного набора типов(native types), а gcnew для другого(managed types). В С++ такого разделения сущностей, конечно же, не будет.

migmit комментирует...

Arseny Kapoulkine
Да я-то понимаю... Потому и не юзаю цепепе. Но так хочется верить в чудо...

Анонимный комментирует...

migmit, если не юзаешь, откуда знаешь, что с++ в ненормальном состоянии?

имхо, конечно, свое мнение по этому поводу может любой заезжий дельфиец высказывать, но серьезно и со смыслом обсуждать С++09 (или, может С++ 0b?) дано "профессионалам" С++

Niraxoid комментирует...

Алёна, а можно ссылочку на исходное сообщение? (чтобы не гуглить :)...)

Алёна комментирует...

2CyberZX:
Сила С++ это в хорошем компромиссе низкоуровневости и высокоуровневости, который не предлагает ни один из других языков.

Так ведь предлагалась опциональная сборка мусора. Так что не хочешь - не используй. И она хотя бы частично решила ту проблему, по поводу которой так волнуется Страуструп - новичкам очень сложно начать программировать на С++.

имхо, конечно, свое мнение по этому поводу может любой заезжий дельфиец высказывать

Что-то беседа стала постепенно перерастает в флейм. Флеймить не надо.

archimed7592 комментирует...

И она хотя бы частично решила ту проблему, по поводу которой так волнуется Страуструп - новичкам очень сложно начать программировать на С++.
Мне кажется, что это далеко не единственная причина по которой вводится GC.

Алёна комментирует...

2Niraxoid:
Алёна, а можно ссылочку на исходное сообщение?
Угу, ссылку я забыла привести.
Trip Report: October 2007 ISO C++ Standards Meeting

Анонимный комментирует...

В чём заключается преимущество GC перед использованием банального подсчёта ссылок в умных указателях?

archimed7592 комментирует...

В чём заключается преимущество GC перед использованием банального подсчёта ссылок в умных указателях?
Хотя бы в том, что GC отрабатывает раз в N секунд, а, в случае с shared_ptr удаление происходит сразу после удаления всех shared_ptr. Соответственно перераспределение памяти постоянное(а в GC переодическое).

Алёна комментирует...

2Анонимный:
В чём заключается преимущество GC перед использованием банального подсчёта ссылок в умных указателях?

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

Niraxoid комментирует...

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

Да, но лучше пусть они сразу выучат азы работы с динамической памятью, чем потом ковыряться в языке. А так пусть python учат :).

Это все равно что детей учат при переходе дороги посмотреть налево а потом направо.
Если детям сказать, что дядя водитель всегда пропустит детей на зеленый свет и они могут просто смотреть на светофор, а не на машины, то можно ого-го скока crash'ей создать.

Я думаю, что GC одним прыжком не получиться реализовать без потери совместимости с текущим стандартом.

Анонимный комментирует...

в случае с shared_ptr удаление происходит сразу после удаления всех shared_ptr
в этом есть свой плюс - предсказуемый и эффективный расход памяти. Ещё у GC какие-то преимущества есть?

CyberZX комментирует...

Вообще, я думаю, в идеале. Надо добавлять не GC в С++. А такие мощные средства мета-программирования, которые позволят без труда реализовать самим программистам тот GC, который им нужен. Это было бы очень круто и полезно. Особенно в геймдеве.

Chabster комментирует...

Herb Sutter уже давно уделяет больше времени C++/CLI, чем C++0x. По сравнению с MC++ это порядочный шаг в светлое будущее .NET, где уже давно есть сборка мусора и все, чего не хватает обычному, некоммерческому С++.

Алёна комментирует...

2Niraxoid:
Да, но лучше пусть они сразу выучат азы работы с динамической памятью, чем потом ковыряться в языке. А так пусть python учат :).

Дык ведь и учат. С++ в связи с этим может недосчитаться программистов.

2CyberZX:
Вообще, я думаю, в идеале. Надо добавлять не GC в С++. А такие мощные средства мета-программирования, которые позволят без труда реализовать самим программистам тот GC, который им нужен.

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

Didro комментирует...

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

archimed7592 комментирует...

Так, например, пока не существует универсальных, надежных не-GC-алгоритмов управления памятью в многопоточных приложениях
0_o...
Про "неуниверсальный" и "ненадёжный" shared_ptr слышал?

Yury Akopov комментирует...

Отсутствие сборки мусора - совершенно правильное решение, если речь идёт о модификации C++, а не о разработке нового языка. Концепция C++ никак не предполагает сборку мусора.

Анонимный комментирует...

> Хотя бы в том, что GC отрабатывает раз в N секунд, а, в случае с shared_ptr удаление происходит сразу после удаления всех shared_ptr

Вы не забывайте о том откуда C++ пришел -- это низкоуровневый язык, т.е. близкий к железу. Если вы можете прикупить пару десятков лишних серверов -- пишите на Java и распределяйте нагрузку.
Iterative GC нынче в моде -- чтобы не зависать время от времени на пару секунд очишая память... А это в-общем и есть shared-ptr. Опять же никто не запрещает написать свой аллокатор, с кучей, и потом освободждать ее один раз... Сила C++ именно в том что он дает возможности, а не решения. Поэтому вводить в него сборку мусора ну совсем не надо.

archimed7592 комментирует...

Последние два оратора: интересно, Вы можете привести хотя бы один пример, где бы приложение с большими требованиями к производительности, стало работать медленее после введения в язык ОПЦИОНАЛЬНОГО GC? Я понимаю, что С++ - первый язык в который будет добавлен опциональный GC и вопрос этот риторический, ибо Вы таких примеров привести не сможете, но подумайте над этим, когда в следующий раз будете высказывать мнение о безполезности GC.

Yury Akopov комментирует...

Дело совершенно не в том, медленнее ли будет работать программа или быстрее.

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

Всё детерменировано, каждый шаг. Именно поэтому на C++ удобнее писать низкоуровневый, системный или же критичный код и менее удобно разрабатывать бизнес-приложения (разработчик загружен ненужной конкретикой вместо абстракций).

В языках с управляемых кодом вообще и сборщиками мусора в частности точно ничего о происходящем в данный момент на уровне физической модели сказать нельзя - только на уровне логической модели. Попробуйте написать систему реального времени на Java, допустим, станет понятнее, о чём речь.

Вот в этом пролегает жёсткая граница между технологиями.

Соответственно, язык со сборщиком мусора просто не может называться развитием C++, это уже новый язык с синтаксисом C++.

Смысла в разработке такого нового языка я вижу ещё меньше, чем в модификации стандарта C++.

archimed7592 комментирует...

Интересно, а Вы сможете точно мне сказать, сколько в каждый момент времени памяти резервируется в стеке, сколько выделяется/освобождается динамической памяти и прочие подробности низкого уровня для любой простейшей программки(подойдёт любой хэлло-ворлд)? Это во-первых.
Во-вторых, не нужно пожалуйста сравнивать Java и С++, и тем более отсылать меня "писать на Джава". С++ и Java - это разные языки. И грань между ними совсем не real-time, а семантика значения, которой нет ни в Java, ни в Delphi, ни в .NET'е. Именно из-за семантики значения я использую этот язык, а совсем не из-за требований к производительности(мне не ставят таких задач).

И, в-третьих, Вы может быть и не видите смысла в этом, но его видят люди из комитета, и главное, что видит его большая часть C++-community.

Yury Akopov комментирует...

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

Однако это практические реализации компиляторов. Сам язык не содержит никаких "чёрных ящиков" и при желании его можно интепретировать "напрямую".

Ввод в язык "умных" элементов эту возможность исключит, и именно здесь, повторю, проходит граница.

Что касается "мнения community", то, боюсь, community в сколько-нибудь значительных масштабах не будет писать ни на C++0x со сборщиком мусора, ни на варианте без оного, как никто не пишет на Oberon. Community вообще всё меньше пишет на C++.

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

P.S. Если уж говорить о желаниях community, то что вы имеете в виду под "семантикой значения"? Google по этому запросу выдаёт всего три ссылки, т.е. пресловутое community не знает ваших критериев. Я догадываюсь, что вы имеете в виду, но хотелось бы уточнить, и для уточнения - как это будет по-английски?

Pigmeich комментирует...

To message
В чём заключается преимущество GC перед использованием банального подсчёта ссылок в умных указателях?

Очень просто - в скорости.

Для начала (чтобы со стула не падать) рассмотрим освобождение памяти:
shared smart pointer (SSP): выхходим из большого алгоритма и прежде чем передать возвращаемое значение, занимаемся деаллокацией. Деаллокация в реализации C-like malloc aka new - это операцией связанная с поиском по памяти маркеров памяти и переписывании их содержимогою. В лучших реализациях - это около 3*int памяти на токен и константное время. Если у нас много указателей на разные области - выбиваемся из кеша процессора.

Garbage Collecting (GC): делаем сборку мусора когда хотим. Обычно, когда муссора накопилось достаточное колличество и приложению нечего делать. Алгоритм сборки потоковый - значит можно реализовать замораживание сборки и юзать кеш.

Теперь про аллокацию. Тут еще веселее - самый быстрый аллоцирующий алгоритм - GC. Аллокация в GC заключается в передвигании указателя конца кучи на размер объекта и возврат исходного указателя (конечно, еще корни пишутся).

Аллокация в malloc - алгоритм выше линейного, посколько необходимо найти нужный участок памяти.

Еще один недостаток SSP - memory leak при образовании циклических ссылок в объектах. В GC проблема легко решается парочкой оптимизационных триков при сборке мусора.

К недостаткам GC - неопределенность времени выполнения деструктора. Впрочем, мест где это надо немного (вроде авто-мьютексов) и если GC is optional - проблемы нет.

archimed7592 комментирует...

в общем случае доподлинно ничего предсказать нельзя - хотя прогноз определённой точности всё-таки делать можно, в отличие от систем со сборщиком мусора - скажем, количественно оценить эффективность одного фрагмента кода перед другим.
Интересно, что же помешает оценке, если этот кусок кода не будет использовать managed resources?

Кроме того, введение в новый стандарт таких принципиальных изменений, как сборка мусора, в значительной мере обессмыслит уже наработанные коды - писать без использования новых элементов уже будет бессмысленно, а переписывание с их учётом будет равноценно переписыванию с нуля, уж больно основополагающая модификация.
Кхм. Очень интересное утверждение. Интересно, после ввода exception specifications Вы ими пользоваться стали? А пришлось ли переписывать из-за этого "уже наработанный код"?

P.S. Если уж говорить о желаниях community, то что вы имеете в виду под "семантикой значения"? Google по этому запросу выдаёт всего три ссылки, т.е. пресловутое community не знает ваших критериев. Я догадываюсь, что вы имеете в виду, но хотелось бы уточнить, и для уточнения - как это будет по-английски?
Ну, во-первых, та фраза к желаниям комьюнити не относилась. Не знаю как это будет по английски - не исключено, что я вообще выдумал этот термин(или очень сильно исковеркал).
Я имел ввиду то, что существуют конструктор, деструктор, конструктор копирования, оператор присваивания, что даются гарантии когда эти ф-ции будут вызваны, ну и то, что в той же Java(и пр. перечисленных мною платформ/ЯП) Вы просто не можете создать объект в стеке. Там нет понятия константности объекта и т.д. Вот это я подразумевал.

К недостаткам GC - неопределенность времени выполнения деструктора. Впрочем, мест где это надо немного (вроде авто-мьютексов) и если GC is optional - проблемы нет.
В местах, где это надо GC просто использовать не нужно. Я не понимаю, кто Вам всем сказал, что автоматические объекты канут в историю 0_о.

Анонимный комментирует...

>делаем сборку мусора когда хотим. Обычно, когда муссора накопилось достаточное колличество и приложению нечего делать

насчет когда хотим -- кастомный аллокатор

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

А "опциональный" gc, это вообще странно... что делать со стыками? или мы скатываемся в new\gcnew из С++\CLI. И вообще, что это такое??? 8)

jazzer комментирует...

Всем, кто говорил про недетерминированность момента удаления объекта при использовании GC:
Вообще-то в случае с shared_ptr (если Вы его, конечно, не используете вместо scoped_ptr) Вы тоже не знаете, в какой момент будет убит объект, так что нет уж такой огромной разницы между GC и shared_ptr в смысле детерминированности момента уничтожения объекта.

Анонимный комментирует...

В местах, где это надо GC просто использовать не нужно. Я не понимаю, кто Вам всем сказал, что автоматические объекты канут в историю 0_о.Ну я так и написал.

Я просто пытался быть объективным и хотел сказать о текущих проблеммах в шарпе.

drinian комментирует...

2archimed7592:
В .NET существует "семантика значения": все типы, производные от System.ValueType, являются типами-значениями (см. различия между классом и структурой в шарпе, различия между перечислениями в шарпе и джаве)

Анонимный комментирует...

archimed7592
Я понимаю, что С++ - первый язык в который будет добавлен опциональный GC
Совсем даже не будет первым. Есть например Cyclone

Анонимный комментирует...

Прежним C++ «ЭТО» не будет, так зачем изобретать вторую Аду? Всё же есть уже. Не пойму я этих ребят.

Анонимный комментирует...

Вообще не понимаю. Хочешь GC программируй в Java или C#, все там есть. Зачем портить гибкость и скорость языка

Анонимный комментирует...

IMHO {
По мне, как в случае введение GC ничего особо мы бы не потеряли/получили, так и если не введут мы ничего особого не получим/потеряем. Да, согласен, что GC много где работает быстрее и эффективнее shared_ptr, auto_ptr. Но опять же, у крупных компаний УЖЕ есть свои наработки GC, если таковой был нужен. А для других не думаю, что так уж КРИТИЧНО понадобится gc.
}

Cj комментирует...

Не хотите мусора? Да на C++ и указатели при желании можно не использовать. Есть же стандартная библиотека для использования динамической памяти, есть безопасные value refrences. Чего же не пользуетесь преимуществами языка?

Cj комментирует...

А для полиморфизма есть в стандартной библиотеки auto_ptr, про boost даже не говорю, сколько там магии есть по типу лямбда функторов.

jart.mail.ru комментирует...

Ну йолки-палки... shared_ptr- это must have при использовании STL-я. Посколько при неиспользовании вы сразу получите overhead на копирование на push/pop, при котором в общем случае могут копироваться и строки, и листы.

А ресурсы типа file handle / handle в Java ни фига сами не высвобождаются. Руками закрывать надо. Поэтому программа пишется в бесконечных try - catch - finally. И не дай бог пропустишь. Java хуже чем С++ в этом отношении. Так что smart pointer / wrapper- это обязательные фичи. Shared pointer только вписывается в общую концепцию безопасного программирования- он не сам-по-себе, он один из.

И GC проблему освобождения ресурсов типа HANDLE не решит, если в объекте живет HANDLE, но его забыли явно грохнуть в деструкторе. А уж какие "качественные" будут плавающие ошибки типа access denied при обращении к ресурсам, освобождение handle'ов которых будет зависеть от таймаута GC... гы-гы-гы.

А память, выделенная специальными функциями API? Тоже GC должен стараться за программиста?

Максим комментирует...

Yury Akopov:
"Соответственно, язык со сборщиком мусора просто не может называться развитием C++, это уже новый язык с синтаксисом C++"

Бьерн Страуструп:
"В С++ надо включить необязательный сборщик мусора"