Path: blob/dev/pkg/protocols/common/protocolstate/memguardian.go
2072 views
package protocolstate12import (3"context"4"sync"5"time"67"github.com/projectdiscovery/gologger"8"github.com/projectdiscovery/utils/env"9httputil "github.com/projectdiscovery/utils/http"10"github.com/projectdiscovery/utils/memguardian"11)1213var (14MaxThreadsOnLowMemory = env.GetEnvOrDefault("MEMGUARDIAN_THREADS", 0)15MaxBytesBufferAllocOnLowMemory = env.GetEnvOrDefault("MEMGUARDIAN_ALLOC", 0)16memTimer *time.Ticker17cancelFunc context.CancelFunc18muGlobalChange sync.Mutex19)2021func StartActiveMemGuardian(ctx context.Context) {22muGlobalChange.Lock()23defer muGlobalChange.Unlock()24if memguardian.DefaultMemGuardian == nil || memTimer != nil {25return26}2728memTimer = time.NewTicker(memguardian.DefaultInterval)29ctx, cancelFunc = context.WithCancel(ctx)30go func() {31for {32select {33case <-ctx.Done():34return35case <-memTimer.C:36if IsLowOnMemory() {37_ = GlobalGuardBytesBufferAlloc()38} else {39GlobalRestoreBytesBufferAlloc()40}41}42}43}()44}4546func StopActiveMemGuardian() {47muGlobalChange.Lock()48defer muGlobalChange.Unlock()4950if memguardian.DefaultMemGuardian == nil {51return52}5354if memTimer != nil {55memTimer.Stop()56cancelFunc()57}58}5960func IsLowOnMemory() bool {61if memguardian.DefaultMemGuardian != nil && memguardian.DefaultMemGuardian.Warning.Load() {62return true63}64return false65}6667// GuardThreads on caller68func GuardThreadsOrDefault(current int) int {69if MaxThreadsOnLowMemory > 0 {70return MaxThreadsOnLowMemory71}7273fraction := int(current / 5)74if fraction > 0 {75return fraction76}7778return 179}8081// Global setting82func GlobalGuardBytesBufferAlloc() error {83if !muGlobalChange.TryLock() {84return nil85}86defer muGlobalChange.Unlock()8788// if current capacity was not reduced decrease it89if MaxBytesBufferAllocOnLowMemory > 0 && httputil.DefaultBytesBufferAlloc == httputil.GetPoolSize() {90gologger.Debug().Msgf("reducing bytes.buffer pool size to: %d", MaxBytesBufferAllocOnLowMemory)91delta := httputil.GetPoolSize() - int64(MaxBytesBufferAllocOnLowMemory)92return httputil.ChangePoolSize(-delta)93}9495return nil96}9798// Global setting99func GlobalRestoreBytesBufferAlloc() {100if !muGlobalChange.TryLock() {101return102}103defer muGlobalChange.Unlock()104105if httputil.DefaultBytesBufferAlloc != httputil.GetPoolSize() {106delta := httputil.DefaultBytesBufferAlloc - httputil.GetPoolSize()107gologger.Debug().Msgf("restoring bytes.buffer pool size to: %d", httputil.DefaultBytesBufferAlloc)108_ = httputil.ChangePoolSize(delta)109}110}111112113