Heim  >  Artikel  >  Backend-Entwicklung  >  Sync Map kann zu einer Erhöhung von RAM und Goroutine führen

Sync Map kann zu einer Erhöhung von RAM und Goroutine führen

PHPz
PHPznach vorne
2024-02-09 18:15:08798Durchsuche

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

php-Editor Youzi erinnert Sie daran, dass die Verwendung von Sync Map zu einer Erhöhung des Arbeitsspeichers und der Goroutine führen kann. Sync Map ist eine Bibliothek in der Go-Sprache, die zur Implementierung parallelitätssicherer Mapping-Datenstrukturen verwendet wird. Obwohl es eine effiziente Leistung bei der Verarbeitung gleichzeitiger Lese- und Schreibvorgänge bietet, kann die Verwendung von Sync Map bei der Verarbeitung großer Datenmengen zu einer Erhöhung der Speichernutzung und der Anzahl von Goroutinen führen. Daher müssen Sie bei der Verwendung von Sync Map das Gleichgewicht zwischen Nutzung und Leistung entsprechend den spezifischen Geschäftsszenarien und -anforderungen abwägen, um die Stabilität und Effizienz des Systems sicherzustellen.

Frageninhalt

Hallo, das ist der Code, mit dem ich util als Sammler bezeichne

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
}

Der Zweck dieses Dienstprogramms besteht also darin, als Cache zu fungieren, in dem ähnliche Werte nur einmal geladen, aber mehrmals gelesen werden. Wenn das Objekt des Kollektors jedoch an mehrere Goroutinen übergeben wird, kommt es immer dann zu einer erhöhten Gorotine- und RAM-Nutzung, wenn mehrere Goroutinen versuchen, den Kollektor-Cache zu nutzen. Kann jemand erklären, ob diese Verwendung synchronisierter Karten korrekt ist? Wenn ja, was könnte dann der Grund für die hohe Anzahl an Goroutinen/den hohen Speicherverbrauch sein?

Problemumgehung

Da die Abbruchfunktion des neu erstellten ctxwithtimeout Kontexts nicht aufgerufen wird, kann es natürlich zu einem Speicherverlust kommen. Um dies zu beheben, ändern Sie die Zeile in:

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

So können Sie jederzeit alle zugewiesenen Ressourcen löschen, sobald der Kontext abläuft. Dies sollte das Leck beheben.
Die Verwendung von sync.map scheint mir in Ordnung zu sein.
Wenn dies Ihr Problem löst oder andere Probleme gelöst werden müssen, lassen Sie es mich bitte wissen, vielen Dank!

Das obige ist der detaillierte Inhalt vonSync Map kann zu einer Erhöhung von RAM und Goroutine führen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:stackoverflow.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen