Как стать автором
Обновить

Комментарии 20

Можно предположить, что 10 000 будет достаточно, но рано или поздно их не хватит, а ожидание 10 001 буфера приведет к остановке алгоритма до момента, пока в канал не вернется пустой фрагмент для дальнейшего переиспользования.

Объясните, пожалуйста, этот момент.

У вас по коду: если канал пустой, то будет создаваться новый буфер. Откуда остановка алгоритма на ожидании возврата буфера в канал?

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

взял код из эксперимента. верну изначальный вариант. Там все буфера предварительно аллоцируются используя sync.Once в начале GetBytes

Большое спасибо за статью!

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

Пропущено слово («решить»?): «проблему можно …»

Если сделать так, что оператор new для переменной типа sync.Pool будет возвращать слайс или другую структуру большого размера, мы попользуемся и сможем вернуть в этот Pool.

Не уверен, что я понял это предложение.

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

Спасибо, что отметили! Внесли правки в текст.

НЛО прилетело и опубликовало эту надпись здесь

jemalloc - это сторонняя библиотека, для которой нужен Cgo

Cgo это плохо априори? Просто если уж вопрос и так стоит об оптимизации, неплохо было бы чекнуть.

Априори - нет, но во многих случаях приложения с cgo работать не смогут, например если собирать OCI контейнер используя FROM scratch, т.к. не будет даже libc

Слайсы и так ссылочный тип. Есть ли смысл использовать их в данных примерах по указателю?

Я извиняюсь, но ваши советы, мягко говоря, не верны. Давайте разберемся.

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

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

Третий вариант, а вот тут самая жесть у вас. Вы верно заметили, что арена должна быть нужного размера, это первая проблема, которая у вас не решена. Возможно вы её оставили на плечи самого реализатора, тогда тут вопросов нет. Но вот возврат, это уже критично. Вы всегда создаёте слайс с N капасити, но при возвращении у вас может прийти слайс с большим капасити. Давайте поразмышляем, что это значит. Это значит, что в тот слайс, который вы брали из этого пула, добавлялись элементы и он был расширен. А значит вы получили уже новый слайс вне арены и, скорее всего, потеряли ссылку на оригинальный слайс из арены и пытаетесь вернуть в пул слайс из не арены. Тут ничего критического, потому что у вас есть проверка. Но проблема заключается в том, что вы первоначальный слайс создавали из арены и когда вы потеряли ссылку на оригинальный слайс, сборщик мусора оригинальный слайс не почистит. Тут у вас будет утечка памяти.

Утечка памяти не будет, так как арены идейно предполагают ручное управление памятью. Т.е. арену надо овободить руками в какой-то момент. А добавление элементов в слайс - как я понимаю, тут дизайн базируется на том, что элементы не будут привышать cap

А если приложение будет работать как демон? А оно явно и будет так работать.

Ну какая разница, демон или нет, тут вопрос времени жизни арены. Если оно равно времени жизни самого приложения, то само использование арены не имеет смысла. Если же это какой-то обработчик, например сообщения из очереди, то проблемы нет - начали обработку, создали арену, выделили слайсы байтов для алгоритма, удалили арену и завершили обработку. Другое дело, что арены в го это очень сырой продукт, который, к пример, до сих пор не решил проблему use after free для таких слайсов и не факт что это будет когда-либо решено, потому что отслеживание времени жизни требует поддержки на уровне языка, как в расте, например, а этого никто делать не будет.

На графике нужно обозначить единицы измерения по оси x и y, не ясно глядя на график что это за цифры

С аренами возникает вопрос - этот пакет имеет сомнительное будущее, может лучше свои арены взять? Ну и как выше заметили, не понятно как контролировать рост слайсов.

Note, 2023-01-17. This proposal is on hold indefinitely due to serious API concerns. The GOEXPERIMENT=arena code may be changed incompatibly or removed at any time, and we do not recommend its use in production

Благодарю автора за статью. Думал, что будет нудятина сложная, а тут весьма доходчиво разобрано. Было интересно читать. Успехов!

Увидел заголовок и сразу подумал - найдется место для арены, или нет?

Нашлось ))

Ну и сразу вопрос - если в работе приложения такие затыки с памятью возникают, есть ли смысл дальше упираться в Go и его GC? Может все-таки C/C++? ))

вообще судя по проблеме видится очевидным при работе с данными не делать промежуточных копий, вы не думали о том чтобы передавать все переменные в каналах концептуально во всем приложении, допустим не аргументом к функции а через канал, канал всегда делает MOVE (не copy & delete)?

Зарегистрируйтесь на Хабре, чтобы оставить комментарий