sync.Pool is geïntroduceerd in Go om tijdelijke objecten te hergebruiken en de druk op de garbage collector te verlagen. Historisch gezien maakten ontwikkelaars hun eigen objectpools met mutexen, wat leidde tot complexe code en mogelijke synchronisatiefouten. sync.Pool is een threadveilige structuur uit de standaardbibliotheek, bedoeld om een object te produceren bij de eerste toegang, dat object op te slaan en het vervolgens terug te geven aan de pool voor hergebruik.
Het probleem is dat als er veel kortlevende objecten zijn (bijvoorbeeld buffertjes in een HTTP-server), het systeem vaak veel tijd verspilt aan allocaties. Het gebruik van sync.Pool stelt ontwikkelaars in staat om optioneel objecten in de cache op te slaan, zonder garantie dat ze in het geheugen blijven, maar het verhoogt de prestaties door het aantal garbage collections te verminderen.
De oplossing is om Pool te gebruiken voor tijdelijke, homogene, snel herbruikbare structuren (bijvoorbeeld bytes.Buffer) door een object terug te geven aan de pool met de methode Put en op te halen met Get. Objecten kunnen op elk moment uit de pool worden verwijderd (bijvoorbeeld bij het starten van de GC), daarom is het niet geschikt voor langdurige opslag.
Voorbeeldcode:
import ( "sync" "bytes" "fmt" ) var bufPool = sync.Pool{ New: func() interface{} { return new(bytes.Buffer) }, } func main() { b := bufPool.Get().(*bytes.Buffer) b.Reset() b.WriteString("hello, world!") fmt.Println(b.String()) bufPool.Put(b) // verplicht teruggeven }
Belangrijke kenmerken:
Kan sync.Pool worden gebruikt voor langdurige opslag van toestanden?
Nee, alle objecten in de Pool kunnen op elk moment door het systeem worden verwijderd (bij GC of bij vermindering van de belasting). Pool is alleen bedoeld voor tijdelijke opslag tussen goroutines.
Garandeert Pool dat precies hetzelfde object wordt teruggegeven dat eerder werd geplaatst?
Nee. Pool geeft elk geschikt object terug of maakt een nieuw object aan indien nodig. Er moet geen koppeling worden opgeslagen tussen de gebruiker en het object van de Pool.
Is het nodig om een object te verwijderen/resetten voordat het wordt teruggegeven aan de Pool?
Ja, anders kan de volgende thread een "vies" object krijgen met resten van vorige gegevens.
Negatieve case
Een ontwikkelaar slaat de status van klanten in de Pool op voor herverbinding met de chat. Na het starten van de GC verdwijnen de verbindingen en verliezen de gebruikers gegevens.
Voordelen:
Nadelen:
Positieve case
Buffer-objecten voor marshal/unmarshal JSON worden in de Pool gestapeld en worden gebruikt voor batchverwerking van berichten. Na verwerking worden de objecten gewassen en teruggegeven aan de pool, waardoor het aantal allocaties wordt verminderd.
Voordelen:
Nadelen: