LINUX.ORG.RU

Про ручное управление памятью


0

5

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

На этот вопрос у меня нет 100% твердой точки зрения, так как я и сам недавно был сторонником ручного управления. Посему вопрос в следующем:

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

А то ведь эти любители ручного управления памятью сами городят в каждом проекте свои смартпоинтеры с подсчетом ссылок и аллокаторы и уверены, что это якобы лучше, чем GC или обычный malloc/free

да. это мой компутер, где свопание неприемлемо

ckotinko ☆☆☆ ()
Ответ на: комментарий от mashina

любой хай лоад

А почему? Из-за невозможности расположить данные в памяти эффективно или из-за времени работы самого GC? Собственно, этот Alv говорит про «числодробилки», в который локальность расположения данных важна, а аллоцировать/деаллоцировать часто там вряд ли нужно.

Т.е. хайлоад без частой аллокации/деаллокации всё ещё может эффективно работать с GC?

knowledge_seeker ()

Какой ужас! ТС, ты о чем вообще?

Anon ()

Посмотри на OCaml и не тупи больше.

tff ()

Просто пища для размышлений

Немного истории: Эпл запилил GC в макосе 10.5, в 10.8 депрекейтнул в пользу ARC. Если бы GC был нужен и годен, Эпл бы так не поступил, согласись? Эрго, GC не нужен.

Apple-ch ★★ ()

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

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

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

А почему? Из-за невозможности расположить данные в памяти эффективно или из-за времени работы самого GC? Собственно, этот Alv говорит про «числодробилки», в который локальность расположения данных важна, а аллоцировать/деаллоцировать часто там вряд ли нужно.

Из-за всего. GC просто не нужен, совсем.

Что нужно для нагруженного сервиса:

1. прогнозируемость поведения (например, latency),

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

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

В хайлоаде часто используют свои аллокаторы, в основном вариации пулов и slab'ов вместе со специальными техниками работы с памятью типа Region-based memory management (используют, например, в nginx, pg). Ещё свои аллокаторы позволяют иметь структурированную реалтаймовую статистику потребления ресурсов.

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

Т.е. хайлоад без частой аллокации/деаллокации всё ещё может эффективно работать с GC?

такого хайлоада почти не бывает. Пришёл запрос в сервис - нужно завести новый объект-эвент, уже минимум +alloc не считая какие-то дополнительные ресурсы. Запросов может быть 10-100 тыс в сек.

mashina ★★★★★ ()

Я бы рассмотрел два класса задач.

1) телеком. То чем я сейчас занимаюсь. Там GC это сразу уволить.. Т.к. время его выполнения неизвестно и это может првести к конретным тормозам, там где время ответа кртитично

2) Веб - там можно просто создавать пул связанный с запросом, выделять память во время обработки запроса в этом пуле, а в конце обработки запроса просто освобождать весь пул. Этот подход мы тоже практикуем.

Ну и быбо бы интересно посмотреть на GC, который работает на Shared Memory. С учетом того, что там используется не адрес, а смещение

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

Помочь посчитать кол-во компонент на с/c++ без GC? Если взял всё готовое и склеил питоном, то это ещё не значит, что клей там является ключевой компонентой.

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

телеком. То чем я сейчас занимаюсь. Там GC это сразу уволить..

То есть Ericsson со своим Erlang'ом — не телеком?

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

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

Считают, и еще как.

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

256Гб на узел - это большой объем памяти или нет?;-)

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

Ютуб на питоне с майскуэлем

То-то он так часто тормозит как сволочь.

FRCTLL ()

Вы никак не угомонитесь... «не бывает серебрянных пуль»(ц). Во все вопли типа «С++/пистон/лисп/.../вижуал бейсик не нужен» аффторы воплей забывают добавлять ключевую фразу "в МОИХ задачах и из МОЕГО СКРОМНОГО ЛИЧНОГО ОПЫТА".

IT то большое, не думаю што бы был хоть один человек, познавший этот дзен целиком и полностью. Но уж если он и есть, то он точно не вопит о том что что-то-там-ненужно (за исключением патентных войн м.б.). И уж тоно он не вопит об этом на ЛОР-е;-)

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

Как показало расследование, эриксон пишет на С/C++/java. Во всяком случае аналог нашего приложения написан именно так. На java скорее всего сдалано управление, клиент итд..

vromanov ★★ ()

свои смартпоинтеры с подсчетом ссылок и аллокаторы и уверены, что это якобы лучше, чем GC или обычный malloc/free

Смарты, как правило, это полуавтоматическое управление с детерминированным удалением(освобождением «других» ресурсов).

Например, std::shared_ptr позволит тебе не следить руками за моментом освобождения, при этом в тот момент, когда будет не нужен объект, он освободит все занятые им ресурсы. И никаких костылей в виде Dispose Pattern и ему подобных. Минус тут в том, что циклические ссылки разруливаются руками. Но, как правило, если они и нужны в языках в духе С++, то крайне редко и прослеживаются в изначальном дизайне. В остальных же случаях это баг, который отслеживается тулзами. Никаких проблем на практике.

forCe ()
Ответ на: комментарий от mashina

Помочь посчитать кол-во компонент на с/c++ без GC?

Основной код на питоне, в этом фишка. Сам питон написан на си и без gc, но это ничего не значит.

true_admin ★★★★★ ()
Ответ на: Просто пища для размышлений от Apple-ch

Re: Просто пища для размышлений

Для гуеты хватит и reference counting. Для серьезных задач нужен полноценный GC.

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

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

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

1) телеком. То чем я сейчас занимаюсь. Там GC это сразу уволить.

то есть товарищи из Ericsson делая erlang всё делают неправильно?

Dark_SavanT ★★★★★ ()

Да много недостатков у GC:

  • Нужно немало дополнительной памяти под нужды GC (GC необходим, как минимум, граф зависимостей между объектами). А оперативная память всё еще не бесплатная.
  • Выделение памяти еще больше замедляется
  • С GC несовместим подход RAII
  • Программа должна периодически прерываться для, собственно, процесса сборки мусора, что портит user experience. Кроме того, GC в общем случае непригоден для риалтайма.
  • GC тянет жирный рантайм => ядро на нем не напишешь (если, конечно, ты не извращенец 80-го уровня, принципиально это не невозможно)

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

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

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

С GC несовместим подход RAII

Мы все плакали.

Программа должна периодически прерываться для, собственно, процесса сборки мусора, что портит user experience.

Про incremental GC не слышал?

Кроме того, GC в общем случае непригоден для риалтайма.

Тут что-то про erlang говорили, но сам я не в курсе

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

Ну raii удобен. мне после плюсов его не хватает. даже try with resources выглядит костылем на этом фоне.

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

Выделение памяти еще больше замедляется

В среднем. malloc() тупит при каждом выделении, копирующий сборщик с поколениями — время от времени (но надолго).

С GC несовместим подход RAII

Это проблемы конкретных джав языков. Управление память и лексическая область видимости — вещи ортогональные.

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

Это проблемы конкретных джав языков.

В теории — да. А на практике не могу припомнить ни одного императивного языка с GC, которому не свойственна такая проблема.

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

Выделение памяти еще больше замедляется

Это не всегда так. Время татят на чістках.

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

Они делают все правильно.. У них сервера пишут сотни программистов, и они требуют для себя шкафа набитого ОХРЕННЕНО дорогими блейдами.

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

Про C# наврал. Но D для структур и C++/CLI для «обычных» С++'ных типов - вполне.

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

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

Ну это же просто бред.

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

GC тянет жирный рантайм => ядро на нем не напишешь (если, конечно, ты не извращенец 80-го уровня, принципиально это не невозможно)

Ну, блин, ну это же совсем не связные вещи.

Смартпоинтеры с подсчетом ссылок имеют гораздо меньшие накладные расходы, чем GC

Больше, больше.

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

Больше, больше.

Смотря как считать. Если смотреть на общие показатели системы(скажем анализировать графики за сутки), то системы с GC ведут себя хуже. Имеют большее время ответов, больше пиков и т.д. Имел опыт сравнения практически идентичных проектов. Правда они были порядка двух-трех человекомесяцев разработки.

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

Т.к. время его выполнения неизвестно

Время выполнения обычного malloc тоже неизвестно (и тем более неконстантно), кстати.

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

Основной код на питоне, в этом фишка.

Возможно он является основным в контексте реализации фронтовой логики, но навряд ли останется таковым же со стороны нагрузки. Например (вырезки с твоего линка):

The Python web code is usually NOT the bottleneck, it spends most of its time blocked on RPCs

Из описания не ясно где пропадают эти RPC, похоже что держит их СУБД

Vitess - a new project released by YouTube, written in Go, it’s a frontend to MySQL. It does a lot of optimization on the fly, it rewrites queries and acts as a proxy. Currently it serves every YouTube database request. It’s RPC based

Мб добрались в их архитектуре до одной из основных компонент в контексте нагрузки, т.е. её держат С'шные сервисы. В качестве полной реализации стека на питоне можно посмотреть на zope, очень тормознутая и неповортливая херня.

Сам питон написан на си и без gc, но это ничего не значит

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

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

Время выполнения обычного malloc тоже неизвестно (и тем более неконстантно), кстати.

malloc() в описанном сценарии используется в основном на прогреве (этап наполнения пулов), далее это пулы с околоконстантным временем работы на allolc/free операции.

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

Vitess - a new project released by YouTube, written in Go, it’s a frontend to MySQL. It does a lot of optimization on the fly, it rewrites queries and acts as a proxy.

Мб добрались в их архитектуре до одной из основных компонент в контексте нагрузки, т.е. её держат С'шные сервисы.

Go - это снова GC.

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

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

vromanov ★★ ()

Вспоминаем 90-е. Много софта, который работает и не тормозит с 8 Мб ОЗУ. Может быть такой софт и не использует оптимально большой объём памяти. Но не тормозит же.

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