Объяснение работы sync.Pool на вёдрах и яблокахВ одном
гошном чатике в сообщениях увидела интересное объяснение, как работает sync.Pool
sync.Pool — это потокобезопасный пул временных объектов в Go. Он помогает переиспользовать объекты, снижая аллокации и нагрузку на GC. Отлично подходит для буферов и временных структур.
Так вот один из участников задал вопрос:
Я не понимаю, чем это отличается от глобальной переменной? Можно же в нее складывать и доставать. Кто может объяснить разницу, пожалуйста?
Объяснение:Глобальная переменная - это ровно одна именованная ячейка памяти. Один объект. А из синк.Пула можно "достать" множество разных, никак не зависящих друг от друга объектов. Потом ненужные - вернуть в пул, потом снова получить из пула. Но при этом эти объекты не будут создаваться в куче и убираться сборщиком мусора каждый раз. Они создаваться будут один раз - при их дефиците, и уничтожатся потом один раз, когда долгое время будут невостребованы.
Представь себе, что ты стоишь на стремянке под деревом и собираешь яблоки И тебе требуется
ведро. Я бегу в магазин,
покупаю ведро, даю его тебе. Ты наполняешь его яблоками, отдаешь его мне, я высыпаю эти яблоки в багажник автомобиля и ведро
выбрасываю.
Ты снова требуешь ведро. Я
снова бегу в магазин, покупаю ведро и отдаю его тебе. И так далее - я всё время покупаю новые вёдра и
выбрасываю их после первого использования.
Так работает выделение-освобождение памяти без sync.PoolЕсли же я буду
работать как sync.Pool, я первый раз побегу за ведром. Если ты у меня потребуешь
еще одно ведро, пока не отдал первое - я снова побегу в магазин. И будет у нас два купленных ведра. Но если ты мне начнешь возвращать ведра,
я не буду их выбрасывать. Я буду их откладывать в сторонку на случай, если ты снова потребуешь у меня ведро. И тогда я тебе отдам ведро не из магазина, а б/у.
И лишь
потом со временем, когда я увижу, что ты давно не требуешь ведра - вот тогда я их грязные, многократно использованные,
выброшу.
А если ты потом потребуешь ведро - я тогда
снова пойду за новым в магазин.
И дополнительный ответ:Если же применить именно глобальную переменную в конкуренции, то придётся использовать мьютекс для потокобезопасности, который замедляет работу высоконагруженного сервиса блокировками на чтение, либо запись. Бутылочное горлышко. А пул это кучка таких переменных, которые распределяют нагрузку.
#go #golang