Skip to content

Instantly share code, notes, and snippets.

@ccfrost
Last active February 15, 2022 01:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ccfrost/11ee33a8242aaa172400a87a435920c7 to your computer and use it in GitHub Desktop.
Save ccfrost/11ee33a8242aaa172400a87a435920c7 to your computer and use it in GitHub Desktop.
package main
import (
"context"
"log"
"runtime"
"strings"
"syscall"
"time"
)
// main simulates the memory use of a general RPC server.
func main() {
// cacheData represents the memory used for a cache.
const cacheDataSize = 1024 * 1024 * 1024
cacheData, err := syscall.Mmap(-1, 0, cacheDataSize,
syscall.PROT_READ|syscall.PROT_WRITE,
syscall.MAP_PRIVATE|syscall.MAP_ANON)
if err != nil {
log.Panicf("mmap failed: %s", err)
}
defer func() {
if err := syscall.Munmap(cacheData); err != nil {
log.Panicf("munmap failed: %s", err)
}
}()
// For benchmarking, write to cacheData to force the kernel to allocate
// the physical memory pages.
for i := 0; i < cacheDataSize; i++ {
cacheData[i] = 'a'
}
// Simulate request serving by repeatedly allocating memory,
// sleeping to simulate the server's work, and then removing
// the reference to the allocated memory.
const requestConcurrency = 128
const totalMemorySize = 64 * 1024 * 1024
const requestMemorySize = totalMemorySize / requestConcurrency
const requestProcessingDuration = 100 * time.Millisecond
for i := 0; i < requestConcurrency; i++ {
go func() {
for {
requestData := strings.Repeat("a", requestMemorySize)
time.Sleep(requestProcessingDuration)
// Reference requestData to keep it from being
// collected until the simulated request is complete.
runtime.KeepAlive(requestData)
// Reference cacheData to keep it from being collected
// while requests are being processed.
runtime.KeepAlive(cacheData)
}
}()
}
// Run the request processing without end.
<-context.Background().Done()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment