Maison  >  Article  >  développement back-end  >  Sync Map peut entraîner une augmentation de la RAM et de la goroutine

Sync Map peut entraîner une augmentation de la RAM et de la goroutine

PHPz
PHPzavant
2024-02-09 18:15:08798parcourir

Sync Map 可能会导致 ram 和 goroutine 的增加

l'éditeur php Youzi vous rappelle que l'utilisation de Sync Map peut entraîner une augmentation de la RAM et de la goroutine. Sync Map est une bibliothèque en langage Go utilisée pour implémenter des structures de données de mappage sécurisées par concurrence. Bien qu'elle offre des performances efficaces lors de la gestion des lectures et écritures simultanées, l'utilisation de Sync Map peut entraîner une augmentation de l'utilisation de la mémoire et du nombre de goroutines lors du traitement de données à grande échelle. Par conséquent, lorsque vous utilisez Sync Map, vous devez peser l'équilibre entre l'utilisation et les performances en fonction de scénarios commerciaux spécifiques et des besoins pour garantir la stabilité et l'efficacité du système.

Contenu de la question

Bonjour, c'est le code où j'appelle util un collectionneur

import (
    "context"
    "errors"
    "sync"
    "time"
)

type Collector struct {
    keyValMap *sync.Map
}

func (c *Collector) LoadOrWait(key any) (retValue any, availability int, err error) {
    value, status := c.getStatusAndValue(key)

    switch status {
    case 0:
        return nil, 0, nil
    case 1:
        return value, 1, nil
    case 2:
        ctxWithTimeout, _ := context.WithTimeout(context.Background(), 5 * time.Second)
        for {
            select {
            case <-ctxWithTimeout.Done():
                return nil, 0, errRequestTimeout
            default:
                value, resourceStatus := c.getStatusAndValue(key)
                if resourceStatus == 1 {
                    return value, 1, nil
                }
                time.Sleep(50 * time.Millisecond)
            }
        }
    }

    return nil, 0, errRequestTimeout
}

// Store ...
func (c *Collector) Store(key any, value any) {
    c.keyValMap.Store(key, value)
}

func (c *Collector) getStatusAndValue(key any) (retValue any, availability int) {
    var empty any
    result, loaded := c.keyValMap.LoadOrStore(key, empty)

    if loaded && result != empty {
        return result, 1
    }

    if loaded && result == empty {
        return empty, 2
    }

    return nil, 0
}

Le but de cet utilitaire est donc d'agir comme un cache où les valeurs similaires ne sont chargées qu'une seule fois mais lues plusieurs fois. Cependant, lorsque l'objet du collecteur est transmis à plusieurs goroutines, je suis confronté à une utilisation accrue de gorotine et de RAM chaque fois que plusieurs goroutines tentent d'utiliser le cache du collecteur. Quelqu'un peut-il expliquer si cette utilisation de cartes synchronisées est correcte. Si oui, quelle pourrait être la raison du nombre élevé de goroutines/utilisation élevée de la mémoire

Solution de contournement

Bien sûr, puisque la fonction d'annulation du contexte ctxwithtimeout nouvellement créé n'est pas appelée, vous pourriez être confronté à une fuite de mémoire. Pour résoudre ce problème, remplacez la ligne par :

ctxWithTimeout, cancelFunc := context.WithTimeout(context.Background(), requestTimeout)
defer cancelFunc()

Vous pouvez ainsi toujours effacer toutes les ressources allouées une fois le contexte expiré. Cela devrait résoudre la fuite.
Concernant l'utilisation de sync.map me semble bien.
Si cela résout votre problème ou s'il y a d'autres problèmes à résoudre, faites-le-moi savoir, merci !

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:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer