Skip to content

Commit

Permalink
initial commit.
Browse files Browse the repository at this point in the history
  • Loading branch information
strategicpause committed Sep 5, 2023
1 parent 1aa6496 commit b20fdbc
Show file tree
Hide file tree
Showing 4 changed files with 107 additions and 1 deletion.
11 changes: 11 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
FROM golang:latest as build

WORKDIR /src
COPY go.mod /src/go.mod
COPY main.go /src/main.go

RUN go build -o /memory-leak

FROM busybox:latest
COPY --from=build /memory-leak /memory-leak
CMD ["/memory-leak"]
17 changes: 16 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,16 @@
# memory-leak
# memory-leak

## Purpose
Recreate scenarios which can invoke the OOM-killer when running a container.

## Build
~~~
podman build . -t memory-leak
~~~

## Run
~~~
$ podman run --memory 500m --name=memory-leak --rm --memory-swap=0 localhost/memory-leak
~~~
By default Podman will enable swap memory with a size equal to the memory limit specified.
This will turn off swap to make sure OOMs can be recreated at the expected memory limit.
3 changes: 3 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module memory-leak

go 1.19
77 changes: 77 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package main

import (
"fmt"
"net/http"
"runtime"
"sync"
"time"
)

const (
MiB = 1024 * 1024
Port = ":8080"
TcpLeak = true
)

func main() {
if TcpLeak {
tcpLeak()
} else {
memoryLeak()
}

}

func tcpLeak() {
wg := sync.WaitGroup{}
wg.Add(1)
go func() {
fmt.Println("Listening on port", Port)
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte(time.Now().String()))
})
http.ListenAndServe(Port, nil)
wg.Done()
}()
for {
go func() {
req := Must(http.NewRequest("GET", "http://localhost:8080/", nil))
client := http.Client{}
Must(client.Do(req))
PrintMemory()
}()
}
wg.Wait()
}

func Must[T any](obj T, err error) T {
if err != nil {
panic(err)
}
return obj
}

func memoryLeak() {
// Allocate 10 GiB in 100 MiB increments
list := make([][]byte, 100)
for i := 0; i < 100; i++ {
list[i] = make([]byte, 100*MiB)
for j := 0; j < 100*MiB; j++ {
list[i][j] = 0
}
PrintMemory()
time.Sleep(time.Second)
}
fmt.Println("Done")
}

func PrintMemory() {
var m runtime.MemStats
runtime.ReadMemStats(&m)
fmt.Printf("TotalAlloc = %v MiB\tSys = %v MiB\n", bToMiB(m.TotalAlloc), bToMiB(m.Sys))
}

func bToMiB(b uint64) uint64 {
return b / 1024 / 1024
}

0 comments on commit b20fdbc

Please sign in to comment.