Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
projectdiscovery
GitHub Repository: projectdiscovery/nuclei
Path: blob/dev/pkg/protocols/common/protocolstate/memguardian.go
2072 views
1
package protocolstate
2
3
import (
4
"context"
5
"sync"
6
"time"
7
8
"github.com/projectdiscovery/gologger"
9
"github.com/projectdiscovery/utils/env"
10
httputil "github.com/projectdiscovery/utils/http"
11
"github.com/projectdiscovery/utils/memguardian"
12
)
13
14
var (
15
MaxThreadsOnLowMemory = env.GetEnvOrDefault("MEMGUARDIAN_THREADS", 0)
16
MaxBytesBufferAllocOnLowMemory = env.GetEnvOrDefault("MEMGUARDIAN_ALLOC", 0)
17
memTimer *time.Ticker
18
cancelFunc context.CancelFunc
19
muGlobalChange sync.Mutex
20
)
21
22
func StartActiveMemGuardian(ctx context.Context) {
23
muGlobalChange.Lock()
24
defer muGlobalChange.Unlock()
25
if memguardian.DefaultMemGuardian == nil || memTimer != nil {
26
return
27
}
28
29
memTimer = time.NewTicker(memguardian.DefaultInterval)
30
ctx, cancelFunc = context.WithCancel(ctx)
31
go func() {
32
for {
33
select {
34
case <-ctx.Done():
35
return
36
case <-memTimer.C:
37
if IsLowOnMemory() {
38
_ = GlobalGuardBytesBufferAlloc()
39
} else {
40
GlobalRestoreBytesBufferAlloc()
41
}
42
}
43
}
44
}()
45
}
46
47
func StopActiveMemGuardian() {
48
muGlobalChange.Lock()
49
defer muGlobalChange.Unlock()
50
51
if memguardian.DefaultMemGuardian == nil {
52
return
53
}
54
55
if memTimer != nil {
56
memTimer.Stop()
57
cancelFunc()
58
}
59
}
60
61
func IsLowOnMemory() bool {
62
if memguardian.DefaultMemGuardian != nil && memguardian.DefaultMemGuardian.Warning.Load() {
63
return true
64
}
65
return false
66
}
67
68
// GuardThreads on caller
69
func GuardThreadsOrDefault(current int) int {
70
if MaxThreadsOnLowMemory > 0 {
71
return MaxThreadsOnLowMemory
72
}
73
74
fraction := int(current / 5)
75
if fraction > 0 {
76
return fraction
77
}
78
79
return 1
80
}
81
82
// Global setting
83
func GlobalGuardBytesBufferAlloc() error {
84
if !muGlobalChange.TryLock() {
85
return nil
86
}
87
defer muGlobalChange.Unlock()
88
89
// if current capacity was not reduced decrease it
90
if MaxBytesBufferAllocOnLowMemory > 0 && httputil.DefaultBytesBufferAlloc == httputil.GetPoolSize() {
91
gologger.Debug().Msgf("reducing bytes.buffer pool size to: %d", MaxBytesBufferAllocOnLowMemory)
92
delta := httputil.GetPoolSize() - int64(MaxBytesBufferAllocOnLowMemory)
93
return httputil.ChangePoolSize(-delta)
94
}
95
96
return nil
97
}
98
99
// Global setting
100
func GlobalRestoreBytesBufferAlloc() {
101
if !muGlobalChange.TryLock() {
102
return
103
}
104
defer muGlobalChange.Unlock()
105
106
if httputil.DefaultBytesBufferAlloc != httputil.GetPoolSize() {
107
delta := httputil.DefaultBytesBufferAlloc - httputil.GetPoolSize()
108
gologger.Debug().Msgf("restoring bytes.buffer pool size to: %d", httputil.DefaultBytesBufferAlloc)
109
_ = httputil.ChangePoolSize(delta)
110
}
111
}
112
113