github.com/etecs-ru/ristretto@v0.9.1/contrib/memtest/main.go (about) 1 /* 2 * Copyright 2020 Dgraph Labs, Inc. and Contributors 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package main 18 19 // #include <stdlib.h> 20 import "C" 21 22 import ( 23 "fmt" 24 "log" 25 "math/rand" 26 "net/http" 27 _ "net/http/pprof" 28 "os" 29 "os/signal" 30 "runtime" 31 "sync/atomic" 32 "syscall" 33 "time" 34 "unsafe" 35 36 "github.com/dustin/go-humanize" 37 "github.com/etecs-ru/ristretto/z" 38 ) 39 40 type S struct { 41 key uint64 42 val []byte 43 next *S 44 inGo bool 45 } 46 47 var ( 48 ssz = int(unsafe.Sizeof(S{})) 49 lo, hi = int64(1 << 30), int64(16 << 30) 50 increase = true 51 stop int32 52 fill []byte 53 maxMB = 32 54 55 cycles int64 = 16 56 ) 57 58 var ( 59 numbytes int64 //nolint:unused,varcheck,gochecknoglobals,lll,deadcode // adopt fork, do not touch it 60 counter int64 //nolint:unused,varcheck,gochecknoglobals,lll,deadcode // adopt fork, do not touch it 61 ) 62 63 func newS(sz int) *S { 64 var s *S 65 if b := Calloc(ssz); len(b) > 0 { 66 s = (*S)(unsafe.Pointer(&b[0])) 67 } else { 68 s = &S{inGo: true} 69 } 70 71 s.val = Calloc(sz) 72 copy(s.val, fill) 73 if s.next != nil { 74 log.Fatalf("news.next must be nil: %p", s.next) 75 } 76 return s 77 } 78 79 func freeS(s *S) { 80 Free(s.val) 81 if !s.inGo { 82 buf := (*[z.MaxArrayLen]byte)(unsafe.Pointer(s))[:ssz:ssz] 83 Free(buf) 84 } 85 } 86 87 func (s *S) allocateNext(sz int) { 88 ns := newS(sz) 89 s.next, ns.next = ns, s.next 90 } 91 92 func (s *S) deallocNext() { 93 if s.next == nil { 94 log.Fatal("next should not be nil") 95 } 96 next := s.next 97 s.next = next.next 98 freeS(next) 99 } 100 101 func memory() { 102 // In normal mode, z.NumAllocBytes would always be zero. So, this program would misbehave. 103 curMem := NumAllocBytes() 104 if increase { 105 if curMem > hi { 106 increase = false 107 } 108 } else { 109 if curMem < lo { 110 increase = true 111 runtime.GC() 112 time.Sleep(3 * time.Second) 113 114 counter++ 115 } 116 } 117 var js z.MemStats 118 z.ReadMemStats(&js) 119 120 fmt.Printf("[%d] Current Memory: %s. Increase? %v, MemStats [Active: %s, Allocated: %s,"+ 121 " Resident: %s, Retained: %s]\n", 122 counter, humanize.IBytes(uint64(curMem)), increase, 123 humanize.IBytes(js.Active), humanize.IBytes(js.Allocated), 124 humanize.IBytes(js.Resident), humanize.IBytes(js.Retained)) 125 } 126 127 func viaLL() { 128 ticker := time.NewTicker(10 * time.Millisecond) 129 defer ticker.Stop() 130 131 root := newS(1) 132 for range ticker.C { 133 if counter >= cycles { 134 fmt.Printf("Finished %d cycles. Deallocating...\n", counter) 135 break 136 } 137 if atomic.LoadInt32(&stop) == 1 { 138 break 139 } 140 if increase { 141 root.allocateNext(rand.Intn(maxMB) << 20) 142 } else { 143 root.deallocNext() 144 } 145 memory() 146 } 147 for root.next != nil { 148 root.deallocNext() 149 memory() 150 } 151 freeS(root) 152 } 153 154 const timeout = 5 * time.Second 155 156 func main() { 157 check() 158 fill = make([]byte, maxMB<<20) 159 rand.Read(fill) 160 161 c := make(chan os.Signal) 162 signal.Notify(c, os.Interrupt, syscall.SIGTERM) 163 go func() { 164 <-c 165 fmt.Println("Stopping") 166 atomic.StoreInt32(&stop, 1) 167 }() 168 go func() { 169 if err := http.ListenAndServe("0.0.0.0:8080", nil); err != nil { 170 log.Fatalf("Error: %v", err) 171 } 172 }() 173 174 viaLL() 175 if left := NumAllocBytes(); left != 0 { 176 log.Fatalf("Unable to deallocate all memory: %v\n", left) 177 } 178 runtime.GC() 179 fmt.Println("Done. Reduced to zero memory usage.") 180 time.Sleep(timeout) 181 }