LINUX.ORG.RU

C++11 и управление памятью

 , ,


0

8

Прочитал недавно о смарт-поинтерах в C++11. Можно ли считать это полноценной заменой GC используемых другими языками программирования, такими как Java/C#? Какие современные компиляторы полноценно поддерживают C++11? Есть ли полноценная поддержка C++14?

★★★★★

Прочитал недавно о смарт-поинтерах в C++11. Можно ли считать это полноценной заменой GC используемых другими языками программирования, такими как Java/C#?

Нет, нельзя.

Manhunt ★★★★★
()

Можно ли считать это полноценной заменой GC используемых другими языками программирования, такими как Java/C#?

Нет.

unique_ptr - единственный владелец объекта, умрет владелец - умрет объект, даже если кто-то на него ссылается.

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

Какие современные компиляторы полноценно поддерживают C++11?

gcc, clang. C С++14 примерно та же ситуация.

anonymous
()
Ответ на: комментарий от ymuv

Смотря через какой умный указатель и GC в C++ нет вообще.

bbk123 ★★★★★
() автор топика
Ответ на: комментарий от anonymous

> Можно ли считать это полноценной заменой GC используемых другими языками программирования, такими как Java/C#?

Нет.

unique_ptr - единственный владелец объекта, умрет владелец - умрет объект, даже если кто-то на него ссылается.

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


Почему же это нельзя считать заменой GC?

bbk123 ★★★★★
() автор топика
Ответ на: комментарий от bbk123

Почему же это нельзя считать заменой GC?

Хотя бы потому, что GC сам разруливает циклические зависимости.

Не, если очень хочется, то можешь считать заменой=)

anonymous
()

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

Какие современные компиляторы полноценно поддерживают C++11?

gcc и clang поддерживают, проприетарщину не вижу смысла рассматривать.

Есть ли полноценная поддержка C++14?

Последний clang поддерживает полностью, про остальных не знаю.

slovazap ★★★★★
()
Последнее исправление: slovazap (всего исправлений: 2)
Ответ на: комментарий от anonymous

Зачем же тогда в Java с её GC ещё в версии 1.2 были добавлены WeakReference, SoftReference, PhantomReference, FinalReference? Подозреваю, что в C# есть всё тоже самое, унаследованное от Java.

bbk123 ★★★★★
() автор топика
Ответ на: комментарий от Pavval

Все, разве что кроме студии.

Да и там не всё так плохо, вроде. Тем более, если учитывать, что автор только про смарт-поинтеры узнал.

DarkEld3r ★★★★★
()
Ответ на: комментарий от bbk123

Зачем же тогда в Java с её GC ещё в версии 1.2 были добавлены WeakReference, SoftReference, PhantomReference, FinalReference?

В Java это оптимизация, в Си++ - необходимость.

tailgunner ★★★★★
()
Ответ на: комментарий от slovazap

В общем случае - нет, из-за возможности кольцевых ссылок.

Почему все говорящии о кольцевых ссылках забывают о weak_ptr? Или при освобождении памяти с кольцевыми ссылками это не помогает?

bbk123 ★★★★★
() автор топика
Ответ на: комментарий от bbk123

Зачем же тогда в Java с её GC ещё в версии 1.2 были добавлены WeakReference, SoftReference, PhantomReference, FinalReference?

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

anonymous
()
Ответ на: комментарий от bbk123

Почему же это нельзя считать заменой GC?

Потому что в ряде случаев подсчет ссылок влечет гораздо бОльшие накладные расходы, чем полноценный GC.

Manhunt ★★★★★
()
Ответ на: комментарий от bbk123

Почему все говорящии о кольцевых ссылках забывают о weak_ptr? Или при освобождении памяти с кольцевыми ссылками это не помогает?

Ну я выше писал о нем. Помогает. Только его нужно прописывать руками. Это можно назвать полуавтоматической сборкой мусора=)

anonymous
()

http://programmers.stackexchange.com/questions/285333/how-does-garbage-collec...

«As for performance both have performance penalties. Automatic reference counting delivers a more consistent performance, no pauses, but slows down your application as a whole as every assignment of an object to a variable, every deallocation of an object, etc, will need an associated incrementation/decrementation of the reference counter, and taking care of reassigning the weak references and calling each destructor of each object being deallocated. GC does not have the performance penalty of ARC when dealing with object references however it incurs pauses while it is collecting garbage (rendering unusable for real-time processing systems) and requires a large memory space in order for it to function effectively such that it is not forced to run, thus pausing execution, too often.»

Manhunt ★★★★★
()
Ответ на: комментарий от tailgunner

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

arturpub ★★
()
Ответ на: комментарий от arturpub

Какая еще оптимизация?

Такая, что GC работает (не допускает утечек) и без них. В Java 1.0 (и вроде бы 1.1) их не было.

tailgunner ★★★★★
()

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

GC обычно откладывает реальное удаление обьектов чтобы сделать это во время простоя процессора или когда уже по другому нельзя будет. Есть и другие преимущества GC. Например некоторые структуры данных, такие как персистентное дерево могут иметь намного более низкую сложность алгоритмов, при условии что расходы амортизировано ложатся на сборку мусора. Некоторые сборщики мусора могут тратить время пропорциональное количеству выживших обьектов со времени последней сборки, а не пропорционально количеству удаленных, что делает сборку мусора очень дешевой. С помощью таких сборщиков мусора также легко реализовывается операция new в куче при сложности O(1) всего парой инструкций процессора, при условии накладных расходов при сборке.

vertexua ★★★★★
()
Ответ на: комментарий от tailgunner

Вот именно. Если не лохматить терминологию в пользу «сам дурак», то объективно память утекает, и нужен либо weak, либо, если его в принципе нет, мутить явные деструкторы, либо не заниматься кешированием и рядом других задач.

arturpub ★★
()
Ответ на: комментарий от bbk123

можно с точки зрения реализуемого функционала.

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

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

next_time ★★★★★
()

Можно ли считать это полноценной заменой GC используемых другими языками программирования, такими как Java/C#?

Конечно, нельзя! Странный вопрос.

dave ★★★★★
()
Ответ на: комментарий от tailgunner

define «утечка»

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

next_time ★★★★★
()
Ответ на: комментарий от tailgunner

Вот именно.

Вот именно что?

Мнение пользователя может не совпадать с мнением GC.

define «утечка»

Невозможность освободить участок памяти по недосмотру программиста (т.е. не предусмотренная программой).

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

arturpub ★★
()
Ответ на: комментарий от arturpub

то очевидно и естественно, что корректный GC такого не допускает, и утечек /такого/ рода в нем не будет

И если ты заинтересован доказать что GC - плохая идея, то легко указать что существуют другие типы утечек и проигнорировать все типы утечек которые таки справляются с помощью GC

vertexua ★★★★★
()
Ответ на: комментарий от arturpub

Вы - нет, я в целом говорю. Во многих спорах выскакивает кто-то с криками «а что если я файл не закрою!»

vertexua ★★★★★
()
Ответ на: комментарий от bbk123

Потому, что GC - это обычно внешний к твоему коду самостоятельный поток, периодически просыпающийся и анализирующий некую структуру, описывающую выделенную твоим кодом память и принимающий решения об освобождении. В принципе shared_ptr можно считать разновидностью GC, но в стандартное понимание это вписывается неточно.

hlamotron
()
Ответ на: комментарий от vertexua

чтобы сделать это во время простоя процессора

минус энергоэффективность. спасибо, что сказать. ноутбук проработает (условно) на 10 минут меньше.

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

а как же вызов деструкторов (нормальные языки с GC, тот же шарп, их умеют) ?

next_time ★★★★★
()
Ответ на: комментарий от next_time

можно с точки зрения реализуемого функционала.

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

Да, вот это точный коммент. С точки зрения функционала - это есть уборщик мусора. Убирает? Да. Что? Мусор. «Ссылки подсчитывает» - это детали реализации, а по смыслу - автоматически убирает мусор. Или выделенная память, про которую все забыли - не есть мусор?

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

hlamotron
()
Ответ на: комментарий от vertexua

Он был приведен в рамках предположения «weak это не необходимость, а не более, чем оптимизация».

arturpub ★★
()
Ответ на: комментарий от next_time

минус энергоэффективность. спасибо, что сказать. ноутбук проработает (условно) на 10 минут меньше.

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

а как же вызов деструкторов (нормальные языки с GC, тот же шарп, их умеют) ?

Обычно их не переопределяют и тут напрашивает оптимизация. Например в Java я на практике НИКОГДА не видел переопределение finalize

vertexua ★★★★★
()
Ответ на: комментарий от hlamotron

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

hlamotron
()
Ответ на: комментарий от ymuv

Это проблема reference counting GC. Более продвинутые GC проверяют доступность и изолированные объекты прибивают.

Midael ★★★★★
()
Последнее исправление: Midael (всего исправлений: 1)
Ответ на: комментарий от vertexua

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

ему для энергоэффективности нужно время полного простоя (если говорить о x86) + запускать дополнительные вычисления лучше тогда, когда процессор уже достаточно нагрелся для запуска вентилятра

next_time ★★★★★
()
Ответ на: комментарий от next_time

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

vertexua ★★★★★
()
Ответ на: комментарий от next_time

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

Если речь о какой-то IDE на Java на ноуте, то есть сомнение что батарея садится из-за сборки мусора, а не из-за общей сложности среды, котороя индексирует очень много данных.

vertexua ★★★★★
()
Ответ на: комментарий от hlamotron

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

А если сделать его асинхронным при помощи обёртки (shared_ptr на обёртку с другим shared_ptr внутри)? Деструктор обёртки просто сделает std::move внутрениму shared_ptr в очередь и дальше тот освобождается в отдельном потоке, похожем на GC. Но в отличии от GC этот поток ничего сам не ищет, а лишь освобождает то, что ему дают.

bbk123 ★★★★★
() автор топика

Раз тут в треде собрался мировой симпозиум экспертов по смарт-поинтерам, то расскажите почему миллиард операций operator->() от shared_ptr медленнее на несколько порядков чем тот же оператор от unique_ptr. Ведь на первый взгляд счетчик не меняется, синхронизация не нужна (ведь если shared_ptr существует в данной строке кода, то гарантирована как минимум одна ссылка)

vertexua ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.