Heim >Backend-Entwicklung >Golang >Verfügt die Go-Sprache über eine Speicherbereinigung?

Verfügt die Go-Sprache über eine Speicherbereinigung?

青灯夜游
青灯夜游Original
2022-12-09 19:42:387057Durchsuche

Go-Sprache verfügt über eine Speicherbereinigung. Die Go-Sprache verfügt über einen Garbage-Collection-Mechanismus (GC); GC wird über einen separaten Prozess ausgeführt. Er sucht nach Variablen, die nicht mehr verwendet werden, und gibt sie frei. in der Berechnung. Der Speicherplatz enthält zwei wichtige Bereiche: den Stapelbereich (Stack) und den Heap-Bereich (Heap). Der Stapelbereich speichert im Allgemeinen die Parameter, Rückgabewerte und lokalen Variablen von Funktionsaufrufen, erzeugt keine Speicherfragmentierung und wird von verwaltet Der Compiler erfordert keine Entwicklung. Der Heap-Bereich generiert Speicherfragmente. In der Go-Sprache werden die Objekte im Heap-Bereich vom Speicherzuweiser zugewiesen und vom Garbage Collector recycelt.

Verfügt die Go-Sprache über eine Speicherbereinigung?

Die Betriebsumgebung dieses Tutorials: Windows 7-System, GO Version 1.18, Dell G3-Computer.

Die Go-Sprache verfügt über einen eigenen Garbage-Collection-Mechanismus (GC). Die GC wird von einem separaten Prozess durchgeführt, der nach nicht mehr verwendeten Variablen sucht und diese freigibt. Es ist zu beachten, dass GC beim Ausführen Maschinenressourcen belegt.

Detaillierte Erklärung von GC, dem Garbage Collection-Mechanismus in der Go-Sprache

In der Informatik ist Garbage Collection (kurz GC) ein automatischer Speicherverwaltungsmechanismus. Der Garbage Collector versucht, Programme zu recyceln, die nicht mehr vorhanden sind Verwendete Objekte und belegter Speicher

Programmierer müssen sich nicht mehr um die manuelle Beantragung und Freigabe des verbleibenden Speichers kümmern, wenn das Programm ausgeführt wird Für Programmierer kann es nur dann angezeigt werden, wenn das Programm eine spezielle Optimierung benötigt, indem eine steuerbare API bereitgestellt wird, um das laufende Timing und den laufenden Overhead von GC zu steuern. Beim Rechnen enthält der Speicherplatz zwei wichtige Bereiche: Den Stapelbereich (Stack). und der Heap-Bereich (Heap); der Stapelbereich speichert im Allgemeinen die Parameter, Rückgabewerte und lokalen Variablen von Funktionsaufrufen, erzeugt keine Speicherfragmentierung, wird vom Compiler verwaltet und erfordert keine Entwicklerverwaltung; Erzeugt eine Speicherfragmentierung. In der Go-Sprache werden Objekte im Heap-Bereich vom Speicherzuweiser zugewiesen und vom Garbage Collector recycelt. [Verwandte Empfehlungen:
Go-Video-Tutorial

,
Programmierunterricht

]Normalerweise ist der Ausführungsprozess des Garbage Collectors in zwei halbunabhängige Komponenten unterteilt:

Benutzerprogramm (Mutator): Benutzermoduscode für GC Mit anderen Worten, der Benutzermoduscode ändert nur die Referenzbeziehung zwischen Objekten.

Collector (Kollektor): Der Code, der für die Durchführung der Speicherbereinigung verantwortlich ist ist nicht mehr verfügbar. Bei Verwendung wird die Go-Speicherverwaltung automatisch von der Standardbibliothek durchgeführt, d. h. die Zuweisung vom Speicher zu Go-Sammlungen. Die Speicherverwaltung umfasst im Allgemeinen drei verschiedene Komponenten, nämlich das Benutzerprogramm (Mutator), den Allokator (Allokator) und den Kollektor (Kollektor). Wenn das Benutzerprogramm Speicher beantragt, beantragt es neuen Speicher über den Speicherzuteiler und den Zuteiler Ist für die Initialisierung des entsprechenden Speicherbereichs aus dem Heap verantwortlich , Bump Allocator)
  • Free-List Allocator (Free-List Allocator)

Linear AllocatorLinear Allocation (Bump Allocator) ist eine effiziente Speicherzuweisungsmethode, hat aber einige Nachteile und große Einschränkungen. Wenn der Benutzer einen linearen Allokator verwendet, muss er nur einen Zeiger auf einen bestimmten Speicherort im Speicher verwalten. Wenn das Benutzerprogramm Speicher vom Allokator anfordert, muss der Allokator nur den verbleibenden freien Speicher überprüfen und den zugewiesenen Speicher zurückgeben Bereich und ändern Sie den Zeiger im Speicherort;

Obwohl der lineare Allokator eine schnellere Ausführungsgeschwindigkeit und eine geringere Implementierungskomplexität aufweist, kann der lineare Allokator den Speicher nicht wiederverwenden, nachdem der Speicher freigegeben wurde. Wie in der Abbildung unten gezeigt, kann der lineare Allokator den roten Speicher nicht wiederverwenden, wenn der zugewiesene Speicher recycelt wird. Daher muss der lineare Allokator in Verbindung mit einem geeigneten Garbage-Collection-Algorithmus verwendet werden. Mark-Compact

Verfügt die Go-Sprache über eine Speicherbereinigung?Kopieren von GC

Generational GC

Der obige Algorithmus kann die überlebenden Objekte durch Kopieren defragmentieren und den freien Speicher regelmäßig zusammenführen, sodass der lineare Allokator verwendet werden kann. Die Effizienz verbessert die Leistung des Speichers allocator

  • Free-List Allocator

  • Free-List Allocator (Free-List Allocator) kann den freigegebenen Speicher wiederverwenden und verwaltet intern eine Datenstruktur ähnlich einer verknüpften Liste. Wenn ein Benutzerprogramm Speicher beantragt, durchläuft der Zuordner für freie verknüpfte Listen die freien Speicherblöcke, um einen ausreichend großen Speicher zu finden, beantragt dann neue Ressourcen und ändert die verknüpfte Liste
  • Verfügt die Go-Sprache über eine Speicherbereinigung?

    Es gibt vier gängige Strategien für kostenlose Zuweisungen verknüpfter Listen:

    • First-Fit – Durchqueren Sie den Kopf der verknüpften Liste und wählen Sie den ersten Speicherblock aus, dessen Größe größer als der angeforderte Speicher ist.
    • Loop First-Fit (Next-Fit) – Durchlaufen Sie die Endposition des letzten Durchlaufs und wählen Sie den ersten Speicherblock aus, dessen Größe größer als der angeforderte Speicher ist. (Best-Fit) – Durchlaufen Sie die gesamte verknüpfte Liste vom Kopf des Verknüpfte Liste und wählen Sie den am besten geeigneten Speicherblock aus. Teilen Sie den Speicher in mehrere verknüpfte Listen auf. Suchen Sie bei der Beantragung von Speicher zunächst nach einer verknüpften Liste , und wählen Sie dann den entsprechenden Speicherblock aus der verknüpften Liste aus
    • Die Vier-in-Eins-Strategie ähnelt der Speicherzuweisungsstrategie, die in der Go-Sprache verwendet wird. Diese Strategie unterteilt den Speicher in eine verknüpfte Liste Bestehend aus 4-, 8-, 16- und 32-Byte-Speicherblöcken. Wenn wir 8 Bytes Speicher vom Speicherzuteiler beantragen, wird der freie Speicherblock gefunden, der die Bedingungen in der obigen Abbildung erfüllt, und zurückgegeben. Die Zuordnungsstrategie der Isolationsanpassung reduziert die Anzahl der Speicherblöcke, die durchlaufen werden müssen, und verbessert die Effizienz der Speicherzuweisung
    • In der Go-Sprache weisen alle Objekte auf dem Heap Speicher zu, indem sie die Funktion
    • runtime.newobject
    aufrufen, die

    runtime.mallocgc

    aufruft, um einen Speicherplatz einer bestimmten Größe zuzuweisen. Dies ist auch eine notwendige Funktion für den Benutzer Programme, die Speicherplatz auf dem Heap beantragen

    func mallocgc(size uintptr, typ *_type, needzero bool) unsafe.Pointer {
    	mp := acquirem()
    	mp.mallocing = 1
    
    	c := gomcache()
    	var x unsafe.Pointer
    	noscan := typ == nil || typ.ptrdata == 0
    	if size <img src="https://img.php.cn/upload/image/909/547/673/167058588792042Verf%C3%BCgt%20die%20Go-Sprache%20%C3%BCber%20eine%20Speicherbereinigung?" title="167058588792042Verfügt die Go-Sprache über eine Speicherbereinigung?" alt="Verfügt die Go-Sprache über eine Speicherbereinigung?">Aus dem Code geht hervor, dass <code>runtime.mallocgc</code> je nach Größe des Objekts unterschiedliche Zuweisungslogiken durchführt und diese in kleine Mikroobjekte unterteilt Objekte und große Objekte entsprechend der Größe des Objekts<p></p>Mikroobjekte <code> (0, 16B)</code> – Verwenden Sie zuerst den Mikro-Allokator und versuchen Sie dann, den Thread-Cache, den zentralen Cache und den zu verwenden Heap zum Zuweisen von Speicher <h3>
    <a id="12_Go__67">Kleine Objekte <code>[16B, 32KB]</code> – Versuchen Sie, abwechselnd den Thread-Cache, den zentralen Cache und den vom Heap zugewiesenen Speicher zu verwenden</a><strong>Großes Objekt <code>(32KB, +∞) – Speicher direkt auf dem Heap zuweisen</code></strong>
    </h3><p><img src="https://img.php.cn/upload%20/image/989/474/411/167058589698786Verf%C3%BCgt%20die%20Go-Sprache%20%C3%BCber%20eine%20Speicherbereinigung?" title="167058589698786Verfügt die Go-Sprache über eine Speicherbereinigung?" alt="Verfügt die Go-Sprache über eine Speicherbereinigung?"></p><p><img src="https://img.php.cn/upload/article/000/000/024/a5c838d9a478159f5ba081935016e79a-Verf%C3%BCgt%20die%20Go-Sprache%20%C3%BCber%20eine%20Speicherbereinigung?" alt="Verfügt die Go-Sprache über eine Speicherbereinigung?">Kleine Zuweisungen</p><p><a href="https://www.php.cn/link/69db85eb5b4279e3182457e176e25b47">Bei kleinen Zuweisungen von weniger als 32 KB versucht Go, mit <code speicher aus dem lokalen cache von>mcache</code> abzurufen, der eine Span-Liste verwaltet (32 KB Speicherblock) <code>mspan</code></a><a href="https://www.php.cn/link/69db85eb5b4279e3182457e176e25b47"><img src="https://img.php.cn/%20upload/image/868/280/984/1670585905314295.png" title="1670585905314295.png " alt="Verfügt die Go-Sprache über eine Speicherbereinigung?"></a></p>Jeder Thread M ist einem Prozessor P zugewiesen und kann höchstens einen Thread nach dem anderen verarbeiten<code>goroutine</code>. Beim Zuweisen von Speicher verwendet die aktuelle <code>goroutine</code> ihren aktuellen lokalen Cache P, um das erste verfügbare freie Objekt in der <code>span</code>-Liste zu finden. <p><code>runtime.mallocgc</code> 根据对象的大小执行不同的分配逻辑,根据对象大小将它们分成微对象、小对象和大对象</p>
    • 微对象 (0, 16B) — 先使用微型分配器,再依次尝试线程缓存、中心缓存和堆分配内存
    • 小对象 [16B, 32KB] — 依次尝试使用线程缓存、中心缓存和堆分配内存
    • 大对象 (32KB, +∞) — 直接在堆上分配内存

    Verfügt die Go-Sprache über eine Speicherbereinigung?

    小分配

    对于小于 32kb 的小分配,Go 会尝试从 mcache 的本地缓存中获取内存,该缓存处理一个跨度列表 (32kb 的内存块) mspan

    Verfügt die Go-Sprache über eine Speicherbereinigung?

    每个线程 M 都分配给一个处理器 P,一次最多处理一个 goroutine。在分配内存时,当前的 goroutine 将使用其当前的本地缓存 P 来查找 span

    Große Zuweisung

    Go tut dies nicht Verwenden Sie den lokalen Cache, um große Zuordnungen zu verwalten. Diese Zuordnungen, die größer als 32 KB sind, werden auf die Seitengröße gerundet und die Seite wird direkt dem Heap zugeordnet

    Verfügt die Go-Sprache über eine Speicherbereinigung?

    2. Garbage Collection In der Go-Sprache der vom Garbage Collector implementierte Algorithmus ist ein gleichzeitiger dreidimensionaler Farbmarkierungs- und Scan-Kollektor.

    Der Garbage Collector läuft gleichzeitig mit dem Go-Programm, sodass ein Algorithmus mit Schreibbarriere erforderlich ist, um potenzielle Änderungen im Speicher zu erkennen. Die einzige Bedingung zum Initiieren einer Schreibbarriere besteht darin, das Programm für einen kurzen Zeitraum anzuhalten, d. h. „Stop the World“

    Der Zweck der Schreibbarriere besteht darin, dem Collector zu ermöglichen, die Datenintegrität auf dem Heap aufrechtzuerhalten während der Sammlung Verfügt die Go-Sprache über eine Speicherbereinigung?

    2.1 Implementierungsprinzip

    Die Garbage Collection der Go-Sprache kann in vier verschiedene Phasen unterteilt werden: klare Beendigung, Markierung, markierte Beendigung und Löschen, von denen zwei Stop The World (STW) generieren

    Beendigungsphase löschenVerfügt die Go-Sprache über eine Speicherbereinigung?

    Pause das Programm, alle Prozessoren gelangen zu diesem Zeitpunkt in den sicheren Punkt

    Wenn der aktuelle Garbage-Collection-Zyklus zwangsweise ausgelöst wird, müssen wir uns auch mit der nicht erfolgten Speicherverwaltungseinheit befassen aufgeräumt
    • mark Stage(STW)
    • Schalten Sie den Status auf _GCmark um, aktivieren Sie Schreibbarrieren, Benutzerprogrammunterstützung (Mutator Assists) und stellen Sie das Stammobjekt in die Warteschlange. _GCmark、开启写屏障、用户程序协助(Mutator Assists)并将根对象入队

    • 恢复执行程序,标记进程和用于协助的用户程序会开始并发标记内存中的对象,写屏障会将被覆盖的指针和新指针都标记成灰色,而所有新创建的对象都会被直接标记成黑色

    • 开始扫描根对象,包括所有 Goroutine 的栈、全局对象以及不在堆中的运行时数据结构,扫描 Goroutine 栈期间会暂停当前处理器

    • 依次处理灰色队列中的对象,将对象标记成黑色并将它们指向的对象标记成灰色

    • 使用分布式的终止算法检查剩余的工作,发现标记阶段完成后进入标记终止阶段

    标记终止阶段 (STW)

    • 暂停程序、将状态切换至 _GCmarktermination 并关闭辅助标记的用户程序
    • 清理处理器上的线程缓存

    清理阶段

    • 将状态切换至 _GCoff

    • Setzen Sie das Ausführungsprogramm fort, markieren Sie den Prozess und das Benutzerprogramm zur Unterstützung Beginnt mit der gleichzeitigen Markierung der Objekte im Speicher, die Schreibbarriere markiert die überschriebenen Zeiger und neuen Zeiger als grau und alle neu erstellten Objekte werden direkt als schwarz markiert

    • Beginnen Sie mit dem Scannen des Stammobjekts, einschließlich des gesamten Goroutine-Stapels , globale Objekte und Laufzeitdatenstrukturen, die sich nicht im Heap befinden, wird der aktuelle Prozessor während des Goroutine-Stack-Scans angehalten

    Verarbeiten Sie die Objekte in der grauen Warteschlange der Reihe nach, markieren Sie die Objekte schwarz und markieren Sie die Objekte, auf die sie verweisen in Grau

    Verwenden Sie den verteilten Beendigungsalgorithmus, um die verbleibende Arbeit zu überprüfen und festzustellen, dass nach Abschluss der Markierungsphase in die Markierungsbeendigungsphase eintritt

      Markierungsbeendigungsphase (STW)
    • Pause das Programm und ändere den Status auf _GCmarktermination und schließe das markierte Hilfsprogramm. <li>Bereinige den Thread-Cache auf dem Prozessor

      Reinigungsphase
    • Wechsel den Status auf _GCoff Code> Starten Sie die Reinigungsphase, initialisieren Sie den Reinigungsstatus und deaktivieren Sie die Schreibsperre<p></p>
    • Stellen Sie das Benutzerprogramm wieder her. Alle neu erstellten Objekte werden weiß markiert. Wenn Goroutine eine neue Speicherverwaltungseinheit beantragt, wird die Bereinigung ausgelöst :

    • Weiße Objekte – potenzieller Müll, dessen Speicher vom Garbage Collector zurückgewonnen werden kann

    Schwarze Objekte – aktive Objekte, einschließlich Objekte, die keinen Verweis auf externe Zeiger und Objekte haben, die vom Stammobjekt aus erreichbar sind 1Verfügt die Go-Sprache über eine Speicherbereinigung?

    Graue Objekte – Aktive Objekte: Da es externe Zeiger gibt, die auf weiße Objekte verweisen, scannt der Garbage Collector diese Objekte

    Wählen Sie ein graues Objekt aus der Sammlung grauer Objekte aus und markieren Sie es schwarz.

    🎜 🎜Markieren Sie alle Objekte, auf die das schwarze Objekt zeigt, als grau, um sicherzustellen, dass weder das Objekt noch die Objekte, auf die das Objekt verweist, recycelt werden.🎜🎜🎜 🎜Wiederholen Sie die beiden oben genannten Schritte, bis im Objektdiagramm keine grauen Objekte mehr vorhanden sind🎜🎜🎜🎜🎜 🎜🎜Weitere Programmierkenntnisse finden Sie unter: 🎜Programmiervideos🎜! ! 🎜

Das obige ist der detaillierte Inhalt vonVerfügt die Go-Sprache über eine Speicherbereinigung?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn