Heim  >  Artikel  >  Backend-Entwicklung  >  Kann das Löschen eines Karteneintrags zu Speicherverlusten in Go führen?

Kann das Löschen eines Karteneintrags zu Speicherverlusten in Go führen?

Patricia Arquette
Patricia ArquetteOriginal
2024-10-24 05:23:30592Durchsuche

Can Deleting a Map Entry Lead to Memory Leaks in Go?

Kann das Löschen eines Karteneintrags zu Speicherlecks in Go führen?

Ein häufiges Problem bei der Manipulation von Datenstrukturen in Go ist die Möglichkeit von Speicherlecks. Diese Frage konzentriert sich darauf, ob das Löschen eines Eintrags aus einer Zeigerkarte zu einem solchen Leck führen kann.

Untersuchung der Quellen

Während die Dokumentation dies nicht explizit anspricht, wird die Go-Laufzeitquelle untersucht Der Code zeigt, dass beim Löschen eines Eintrags aus einer Karte sowohl der Schlüssel- als auch der Wertspeicher gelöscht (auf Null gesetzt) ​​werden. Dies bedeutet, dass alle darin enthaltenen Zeiger ebenfalls gelöscht werden.

// Clear key storage.
memclr(k, uintptr(t.keysize))
// Clear value storage.
v := unsafe.Pointer(uintptr(unsafe.Pointer(b)) + dataOffset + bucketCnt*uintptr(t.keysize) + i*uintptr(t.valuesize))
memclr(v, uintptr(t.valuesize))

Beweis anhand eines Beispiels

Um dies zu untermauern, können wir ein Beispielprogramm mit einer Karte von Zeigern erstellen und einen Finalizer dafür registrieren fangen, wenn der Zeiger nicht mehr erreichbar ist:

import (
    "fmt"
    "runtime"
    "sync"
    "time"
)

type point struct {
    X, Y int
}

func main() {
    // Create a map and put a pointer value in it, with a finalizer.
    m := map[int]*point{}
    p := &point{1, 2}
    runtime.SetFinalizer(p, func(p *point) {
        fmt.Printf("Finalized: %p %+v\n", p, p)
    })
    m[1] = p
    fmt.Printf("Put in map: %p %+v\n", p, p)

    // Delete the entry from the map.
    delete(m, 1)

    // Force garbage collection.
    runtime.GC()

    // Sleep to ensure the finalizer has a chance to run.
    time.Sleep(time.Second)

    // Print the map to verify the map itself wasn't garbage collected.
    fmt.Println(m)
}

Wenn Sie dies ausführen, wird die folgende Ausgabe erzeugt:

Put in map: 0x1040a128 &{X:1 Y:2}
Finalized: 0x1040a128 &{X:1 Y:2}
map[]

Wie Sie sehen können, wird der Finalizer aufgerufen, wenn der Zeiger von der Karte entfernt wird und wird unerreichbar, was zeigt, dass kein Speicherverlust vorliegt.

Das obige ist der detaillierte Inhalt vonKann das Löschen eines Karteneintrags zu Speicherverlusten in Go führen?. 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