Created
February 13, 2017 15:32
-
-
Save elazarl/c7ff1be55e0d2bd008f6a46f606e239e to your computer and use it in GitHub Desktop.
Creating fragmentation on purpose to crash golang's GC
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// This tiny program show how to cause fragmentation in golang, killing it | |
// even though no real memory is actually used. | |
// Compile: | |
// $ go build frag.go | |
// Run: | |
// $ time (setrlimit $[100*1000];./frag) | |
// .....(until it crashes) | |
package main | |
import "fmt" | |
const TIMES = 10 * 1000 | |
func alloc_90_10(times, _90, _10 int, p *interface{}) { | |
for ; times > 0; times-- { | |
for i := 0; i < 9; i++ { | |
*p = make([]byte, _90) | |
} | |
*p = make([]byte, _10) | |
} | |
} | |
func main() { | |
// trick the compiler not to dicard the unused allocation | |
// IMPORTANT, as Go compiler becomes smarter, this little program might | |
// be compiled to no-op. | |
var x interface{} | |
dots := uint64(0) | |
for { | |
alloc_90_10(TIMES, 100, 47*1024, &x) | |
alloc_90_10(TIMES, 47*1024, 100, &x) | |
fmt.Print(".") | |
dots++ | |
if dots%80 == 79 { | |
fmt.Println() | |
} | |
} | |
} | |
/* | |
Example run on go version go1.7.4 linux/amd64 | |
Given virtual memory limit of 100MB: | |
⮀ time (ulimit -Sv 100000; ~/frag) | |
.....fatal error: runtime: out of memory | |
runtime stack: | |
runtime.throw(0x4a718a, 0x16) | |
/usr/local/go/src/runtime/panic.go:566 +0x95 | |
runtime.sysMap(0xc425a00000, 0x100000, 0x7fc7e4e72100, 0x515e58) | |
/usr/local/go/src/runtime/mem_linux.go:219 +0x1d0 | |
runtime.(*mheap).sysAlloc(0x4fd640, 0x100000, 0x4faac0) | |
/usr/local/go/src/runtime/malloc.go:407 +0x37a | |
runtime.(*mheap).grow(0x4fd640, 0x6, 0x0) | |
/usr/local/go/src/runtime/mheap.go:726 +0x62 | |
runtime.(*mheap).allocSpanLocked(0x4fd640, 0x6, 0x7ffd18061aa0) | |
/usr/local/go/src/runtime/mheap.go:630 +0x4f2 | |
runtime.(*mheap).alloc_m(0x4fd640, 0x6, 0x100000000, 0x7fc7e4e720a0) | |
/usr/local/go/src/runtime/mheap.go:515 +0xe0 | |
runtime.(*mheap).alloc.func1() | |
/usr/local/go/src/runtime/mheap.go:579 +0x4b | |
runtime.systemstack(0x7ffd18061b10) | |
/usr/local/go/src/runtime/asm_amd64.s:314 +0xab | |
runtime.(*mheap).alloc(0x4fd640, 0x6, 0x10100000000, 0x2d) | |
/usr/local/go/src/runtime/mheap.go:580 +0x73 | |
runtime.largeAlloc(0xbc00, 0x448301, 0xc420048f20) | |
/usr/local/go/src/runtime/malloc.go:774 +0x93 | |
runtime.mallocgc.func1() | |
/usr/local/go/src/runtime/malloc.go:669 +0x3e | |
runtime.systemstack(0x4fa700) | |
/usr/local/go/src/runtime/asm_amd64.s:298 +0x79 | |
runtime.mstart() | |
/usr/local/go/src/runtime/proc.go:1079 | |
goroutine 1 [running]: | |
runtime.systemstack_switch() | |
/usr/local/go/src/runtime/asm_amd64.s:252 fp=0xc420048d70 sp=0xc420048d68 | |
runtime.mallocgc(0xbc00, 0x48a6a0, 0xc420048e01, 0x40e64d) | |
/usr/local/go/src/runtime/malloc.go:670 +0x903 fp=0xc420048e10 sp=0xc420048d70 | |
runtime.makeslice(0x48a6a0, 0xbc00, 0xbc00, 0x489560, 0xc42581c5a0, 0xbc00) | |
/usr/local/go/src/runtime/slice.go:57 +0x7b fp=0xc420048e68 sp=0xc420048e10 | |
main.alloc_90_10(0x8af, 0xbc00, 0x64, 0xc420048f18) | |
/home/elazar/frag.go:10 +0x67 fp=0xc420048ee0 sp=0xc420048e68 | |
main.main() | |
/home/elazar/frag.go:22 +0x94 fp=0xc420048f58 sp=0xc420048ee0 | |
runtime.main() | |
/usr/local/go/src/runtime/proc.go:183 +0x1f4 fp=0xc420048fb0 sp=0xc420048f58 | |
runtime.goexit() | |
/usr/local/go/src/runtime/asm_amd64.s:2086 +0x1 fp=0xc420048fb8 sp=0xc420048fb0 | |
( ulimit -Sv 100000; ~/frag; ) 6.14s user 0.38s system 126% cpu 5.157 total | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
something like this maybe?
javac Frag.java && java -Xmx1g -cp . Frag