garbage-collection - collection - garbage collector java 8



Wie Minimierung der Speicherbereinigung in Go? (2)

Vermeiden Müll ist relativ geradlinig. Sie müssen wissen, wo die Zuweisungen vorgenommen werden, und sehen, ob Sie die Zuweisung vermeiden können.

Erstens wird das Deklarieren von Variablen am Anfang einer Funktion NICHT helfen. Der Compiler kennt den Unterschied nicht. Aber der Mensch wird den Unterschied kennen und er wird sie ärgern.

Die Verwendung eines Arrays anstelle eines Slice funktioniert, aber das liegt daran, dass Arrays (außer dereferenziert) auf den Stack gelegt werden. Arrays haben andere Probleme wie die Tatsache, dass sie nach Wert zwischen Funktionen übergeben (kopiert) werden. Alles auf dem Stapel ist "nicht Müll", da es freigegeben wird, wenn die Funktion zurückkehrt. Jeder Pointer oder Slice, der die Funktion verlassen kann, wird auf den Heap gesetzt, mit dem der Garbage Collector zu einem bestimmten Zeitpunkt fertig werden muss.

Das Beste, was Sie tun können, ist die Zuteilung zu vermeiden. Wenn Sie mit großen Datenmengen fertig sind, die Sie nicht benötigen, verwenden Sie sie erneut. Dies ist die Methode, die im Profiling-Lernprogramm auf dem Go-Blog verwendet wird. Ich schlage vor, es zu lesen.

Ein weiteres Beispiel neben dem im Profiling-Tutorial: Nehmen wir an, Sie haben eine Scheibe vom Typ []int Namen xs . Sie hängen fortlaufend an []int bis Sie eine Bedingung erreichen, und Sie setzen es dann zurück, so dass Sie von vorn beginnen können. Wenn Sie xs = nil , deklarieren Sie jetzt das zugrunde liegende Array des Slice als zu sammelnden Müll. Append wird xs beim nächsten Mal neu zuweisen. Wenn Sie stattdessen xs = xs[:0] , setzen Sie es immer noch zurück, behalten aber das alte Array bei.

Der Versuch, Müll zu vermeiden, ist in den meisten Fällen eine vorzeitige Optimierung. Für die meisten Ihres Codes spielt es keine Rolle. Aber Sie können ab und zu eine Funktion finden, die sehr oft aufgerufen wird, die bei jeder Ausführung viel zuweist. Oder eine Schleife, bei der Sie sie neu zuweisen anstatt sie erneut zu verwenden. Ich würde warten, bis Sie den Flaschenhals sehen, bevor Sie über Bord gehen.

https://src-bin.com

Manchmal könnten Sie den Garbage Collector vermeiden / minimieren wollen, also möchte ich sicher sein, wie es geht.

Ich denke, dass der nächste richtig ist:

  • Deklariere Variablen am Anfang der Funktion.
  • Um Array anstelle von Slice zu verwenden.

Nicht mehr?


Answer #1

Um die Speicherbereinigung in Go zu minimieren, müssen Sie die Heapzuweisungen minimieren. Um die Zuweisung von Heap zu minimieren, müssen Sie verstehen, wann Zuteilungen passieren.

Die folgenden Dinge verursachen immer Zuordnungen (zumindest im GC Compiler ab Go 1):

  • Verwenden der new integrierten Funktion
  • Verwenden der integrierten Funktion make (außer in einigen wenigen unwahrscheinlichen Fällen)
  • Zusammengesetzte Literale, wenn der Werttyp ein Slice, eine Map oder eine Struktur mit dem Operator &
  • Einen Wert größer als ein Maschinenwort in eine Schnittstelle eingeben. (Beispielsweise sind Zeichenfolgen, Segmente und einige Strukturen größer als ein Maschinenwort.)
  • Konvertieren zwischen string , []byte und []rune
    • Ab Go 1.3 weist der Compiler diesen Ausdruck nicht auf: m[string(b)] , wobei m eine Map und b ein []byte
  • Konvertieren eines nicht konstanten ganzzahligen Werts in eine string
  • defer Aussagen
  • go Anweisungen
  • Funktionsliterale, die lokale Variablen erfassen

Die folgenden Dinge können abhängig von den Details Zuweisungen verursachen:

  • Die Adresse einer Variablen nehmen. Beachten Sie, dass Adressen implizit übernommen werden können. Zum Beispiel könnte ab() die Adresse von a wenn a kein Zeiger ist und die b Methode einen Zeigerempfängertyp hat.
  • Verwenden der integrierten Funktion append
  • Aufruf einer variadischen Funktion oder Methode
  • Slicing eines Arrays
  • Hinzufügen eines Elements zu einer Karte

Die Liste soll vollständig sein und ich bin einigermaßen zuversichtlich darin, aber ich freue mich über Ergänzungen oder Korrekturen.

Wenn Sie sich nicht sicher sind, wo Ihre Zuweisungen stattfinden, können Sie sich immer so profilieren, wie andere vorgeschlagen haben, oder sich die vom Compiler erstellte Assembly anschauen.





go