sync.Pool wurde in Go eingeführt, um temporäre Objekte wiederzuverwenden und den Druck auf den Garbage Collector zu reduzieren. Historisch gesehen haben Entwickler eigene Objektepools unter Verwendung von Mutexen erstellt, was zu komplexem Code und möglichen Synchronisationsfehlern führte. sync.Pool ist eine thread-sichere Struktur aus der Standardbibliothek, die dazu dient, ein Objekt beim ersten Zugriff zu erzeugen, es zu speichern und dieses Objekt anschließend zurück in den Pool zur Wiederverwendung zu geben.
Das Problem ist, dass beim großen Aufkommen von kurzlebigen Objekten (z.B. Puffern in einem HTTP-Server) das System oft viel Zeit für Zuweisungen benötigt. Die Verwendung von sync.Pool ermöglicht es fakultativ, Objekte zwischenzuspeichern, ohne ihre Erhaltung im Speicher zu garantieren, jedoch die Leistung durch Verringerung der Anzahl von Garbage Collections zu steigern.
Die Lösung besteht darin, einen Pool für temporäre, homogene, schnell verwendbare Strukturen (z.B. bytes.Buffer) zu verwenden, indem das Objekt mit der Methode Put zurückgegeben und mit Get abgerufen wird. Objekte können jederzeit aus dem Pool entfernt werden (z.B. beim GC-Start), daher eignet sich der Pool nicht für die langfristige Speicherung.
Beispielcode:
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) // unbedingt zurückgeben }
Schlüsselmerkmale:
Kann sync.Pool für die langfristige Speicherung von Zuständen verwendet werden?
Nein, alle Objekte im Pool können jederzeit vom System entfernt werden (bei GC oder Lastreduzierung). Der Pool ist nur für temporäre Speicherungen zwischen Goroutinen gedacht.
Garantiere der Pool die Rückgabe genau des Objekts, das zuvor eingefügt wurde?
Nein. Der Pool gibt jedes geeignete Objekt zurück oder erstellt bei Bedarf ein neues. Es sollte keine Bindung zwischen Benutzer und Objekt des Pools bestehen.
Muss das Objekt vor der Rückgabe in den Pool bereinigt/reset werden?
Ja, sonst könnte der nächste Thread ein "schmutziges" Objekt mit Restdaten der vorherigen Daten erhalten.
Negativer Fall
Ein Entwickler speichert die Zustände von Clients im Pool für eine Wiederverbindung zum Chat. Nach dem Start von GC verschwinden die Verbindungen, und Benutzer verlieren ihre Daten.
Vorteile:
Nachteile:
Positiver Fall
Buffer-Objekte zum Marshallen/Unmarshallen von JSON werden im Pool gespeichert und für die Batchverarbeitung von Nachrichten verwendet. Nach der Verarbeitung werden die Objekte bereinigt und in den Pool zurückgegeben, wodurch die Anzahl der Zuweisungen verringert wird.
Vorteile:
Nachteile: