Heim >Backend-Entwicklung >Golang >Warum benötigt Go für ein Slice mit einer Länge von 100 KB weniger Speicher als für ein Array mit einer Länge von 100 KB?
Wenn die Go-Sprache Slices und Arrays verarbeitet, benötigt ein Slice mit einer Länge von 100 KB weniger Speicher als ein Array mit einer Länge von 100 KB. Dies liegt daran, dass Slices in ihrer zugrunde liegenden Implementierung eine Kombination aus Zeigern und Längen verwenden, während Arrays zusammenhängenden Speicherplatz zum Speichern von Daten benötigen. Da die Länge eines Slice variabel ist, kann Speicher dynamisch zugewiesen und freigegeben werden, während für ein Array bei der Deklaration eine feste Länge angegeben werden muss. Daher kann die Verwendung von Slicing bei der Verarbeitung großer Datenmengen den Speicherplatz effizienter nutzen und die Speichernutzung reduzieren. Dies ist auch einer der Vorteile der Go-Sprache bei der Verarbeitung großer Datenmengen.
Betrachten Sie den folgenden Code, ich habe 4000 Arrays mit jeweils 100.000 Längen zugewiesen:
parentmap := make(map[int][100_000]int) for i := 0; i < 4000; i++ { parentmap[i] = [100_000]int{} time.sleep(3 * time.millisecond) }
Wenn ich das Programm lokal ausführe und seine Speichernutzung analysiere, beginnt es, mehr als 2 GB Speicher zu verbrauchen.
Wenn wir nun den Code leicht ändern, um Array-Slices (aber auch mit einer Länge von 100 KB) wie folgt zu verwenden:
parentMap := make(map[int][]int) for i := 0; i < 4000; i++ { parentMap[i] = make([]int, 100_000) time.Sleep(3 * time.Millisecond) }
Auf meinem Computer erreichte der Speicher seinen Höhepunkt bei etwa 73 MB. Warum ist das so?
Ich denke, dass beide Fragmente aus folgenden Gründen ungefähr den gleichen Speicher nutzen werden:
parentmap
的值。 go 这样做是因为如果它在堆栈上分配这些值,那么一旦当前函数超出范围,parentmap
auf dem Heap zu und alle Werte werden gelöscht. Ich habe gelesen: https://go.dev/blog/slices-intro. Ich kann jedoch keine Implementierungsdetails finden, die dies erklären.
Die Version mit Slicing könnte von der Lazy Allocation profitieren. Es wird nicht versucht, in die Datenpuffer in einem dieser Slices zu schreiben, daher steht es dem Betriebssystem frei, diesen Puffern erst dann tatsächlich Speicher zuzuweisen, wenn tatsächlich ein Schreibversuch unternommen wird. (Das Betriebssystem kann Puffer auch langsam auf Null initialisieren, sodass Zuweisungen nicht erzwungen werden.)
In der Zwischenzeit erfordert die Version mit einem Array, dass das Array tatsächlich in die Karte kopiert wird, was bedeutet, dass der Schreibvorgang tatsächlich ausgeführt wird. Selbst wenn die geschriebenen Werte alle Nullen sind, handelt es sich dennoch um Schreibvorgänge, sodass das Betriebssystem tatsächlich Speicher für die zu schreibenden Daten zuweisen muss.
Versuchen Sie, Daten in diese Slices zu schreiben. Die Sliced-Version sollte ebenfalls Gigabyte Speicher beanspruchen. (Ich denke, ein Wert pro Speicherseite sollte ausreichen, aber es könnte einfacher sein, das Slice mit 1
s zu füllen.)
Das obige ist der detaillierte Inhalt vonWarum benötigt Go für ein Slice mit einer Länge von 100 KB weniger Speicher als für ein Array mit einer Länge von 100 KB?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!