github.com/iDigitalFlame/xmt@v0.5.4/com/limits/sweep.go (about) 1 //go:build !nosweep 2 // +build !nosweep 3 4 // Copyright (C) 2020 - 2023 iDigitalFlame 5 // 6 // This program is free software: you can redistribute it and/or modify 7 // it under the terms of the GNU General Public License as published by 8 // the Free Software Foundation, either version 3 of the License, or 9 // any later version. 10 // 11 // This program is distributed in the hope that it will be useful, 12 // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 // GNU General Public License for more details. 15 // 16 // You should have received a copy of the GNU General Public License 17 // along with this program. If not, see <https://www.gnu.org/licenses/>. 18 // 19 20 package limits 21 22 import ( 23 "context" 24 "runtime" 25 "runtime/debug" 26 "sync/atomic" 27 "time" 28 29 "github.com/iDigitalFlame/xmt/device" 30 "github.com/iDigitalFlame/xmt/util/bugtrack" 31 ) 32 33 var enabled uint32 34 35 // MemorySweep enables the GC memory sweeper, which keeps the process memory 36 // clean to prevent any crashes while in DLL format or injected. This function 37 // only needs to be called once and will return immediately. 38 // 39 // The context is recommended to prevent any leaking Goroutines from being left 40 // behind. 41 // 42 // Defaults to a time of one minute. 43 func MemorySweep(x context.Context) { 44 MemorySweepEx(x, time.Minute) 45 } 46 func sweep(x context.Context, t time.Duration) { 47 v := time.NewTicker(t) 48 loop: 49 for { 50 select { 51 case <-v.C: 52 case <-x.Done(): 53 break loop 54 } 55 if bugtrack.Enabled { 56 bugtrack.Track("limits.sweep(): Starting GC and Free.") 57 } 58 runtime.GC() 59 device.FreeOSMemory() 60 } 61 if v.Stop(); bugtrack.Enabled { 62 bugtrack.Track("limits.sweep(): Stopping GC and Free thread.") 63 } 64 } 65 66 // MemorySweepEx enables the GC memory sweeper, which keeps the process memory 67 // clean to prevent any crashes while in DLL format or injected. This function 68 // only needs to be called once and will return immediately. 69 // 70 // The context is recommended to prevent any leaking Goroutines from being left 71 // behind. 72 // 73 // Allows for specification of the time span between sweeps. 74 func MemorySweepEx(x context.Context, d time.Duration) { 75 if d <= 0 || atomic.LoadUint32(&enabled) == 1 { 76 return 77 } 78 debug.SetGCPercent(60) 79 debug.SetTraceback("none") 80 runtime.SetCPUProfileRate(0) 81 runtime.SetBlockProfileRate(0) 82 runtime.SetMutexProfileFraction(0) 83 // NOTE(dij): Let's ignore this one for now. 84 // We'll set it in our own env. 85 // runtime.GOMAXPROCS(runtime.NumCPU()) 86 atomic.StoreUint32(&enabled, 1) 87 go sweep(x, d) 88 }