Maison  >  Article  >  développement back-end  >  La suppression d’une entrée de carte peut-elle entraîner des fuites de mémoire dans Go ?

La suppression d’une entrée de carte peut-elle entraîner des fuites de mémoire dans Go ?

Patricia Arquette
Patricia Arquetteoriginal
2024-10-24 05:23:30591parcourir

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

La suppression d'une entrée de carte peut-elle provoquer des fuites de mémoire dans Go ?

Une préoccupation courante lors de la manipulation de structures de données dans Go est le potentiel de fuites de mémoire. Cette question se concentre sur la question de savoir si la suppression d'une entrée d'une carte de pointeurs peut conduire à une telle fuite.

Examen des sources

Bien que la documentation n'aborde pas explicitement ce problème, inspecter la source d'exécution Go Le code révèle que lorsqu'une entrée est supprimée d'une carte, le stockage de la clé et de la valeur est effacé (mis à zéro). Cela signifie que tous les pointeurs contenus à l'intérieur sont également effacés.

// 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))

Le prouver avec un exemple

Pour corroborer cela, nous pouvons créer un exemple de programme avec une carte de pointeurs et enregistrer un finaliseur pour catch lorsque le pointeur devient inaccessible :

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)
}

L'exécution de cette opération produira le résultat suivant :

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

Comme vous pouvez le voir, le finaliseur est appelé lorsque le pointeur est supprimé de la carte et devient inaccessible, démontrant qu'il n'y a pas de fuite de mémoire.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn