运行时:内存不足但仍有内存

最近发生了一个非常奇怪的问题。我的程序在一个有 8GB 内存的 docker 上运行,当发生恐慌时使用了 4GB。有超过 4GB 的可用内存,为什么会发生这种情况?下面是恐慌堆栈输出。


# ulimit -m

unlimited


# go version

1.6.2

我尝试反复运行代码行getAllCombinationComplex,内存使用量增长到大约 5GB,但恐慌并没有再次发生。


fatal error: runtime: out of memory


runtime stack:

runtime.throw(0xd28a90, 0x16)

        /usr/local/go1.6.2/src/runtime/panic.go:547 +0x90

runtime.sysMap(0xf409e80000, 0x3ecc390000, 0x434a00, 0x1080918)

        /usr/local/go1.6.2/src/runtime/mem_linux.go:206 +0x9b

runtime.(*mheap).sysAlloc(0x1066280, 0x3ecc390000, 0xdfc4d6d680)

        /usr/local/go1.6.2/src/runtime/malloc.go:429 +0x191

runtime.(*mheap).grow(0x1066280, 0x1f661c8, 0x0)

        /usr/local/go1.6.2/src/runtime/mheap.go:651 +0x63

runtime.(*mheap).allocSpanLocked(0x1066280, 0x1f661c4, 0x10677f0)

        /usr/local/go1.6.2/src/runtime/mheap.go:553 +0x4f6

runtime.(*mheap).alloc_m(0x1066280, 0x1f661c4, 0xffffff0100000000, 0x7ff85dbfddd0)

        /usr/local/go1.6.2/src/runtime/mheap.go:437 +0x119

runtime.(*mheap).alloc.func1()

        /usr/local/go1.6.2/src/runtime/mheap.go:502 +0x41

runtime.systemstack(0x7ff85dbfdde8)

        /usr/local/go1.6.2/src/runtime/asm_amd64.s:307 +0xab

runtime.(*mheap).alloc(0x1066280, 0x1f661c4, 0x10100000000, 0x41587c)

        /usr/local/go1.6.2/src/runtime/mheap.go:503 +0x63

runtime.largeAlloc(0x3ecc386800, 0x7ff800000000, 0x6)

        /usr/local/go1.6.2/src/runtime/malloc.go:766 +0xb3

runtime.mallocgc.func3()

        /usr/local/go1.6.2/src/runtime/malloc.go:664 +0x33

runtime.systemstack(0xc820028000)

        /usr/local/go1.6.2/src/runtime/asm_amd64.s:291 +0x79

runtime.mstart()

        /usr/local/go1.6.2/src/runtime/proc.go:1051

莫回无
浏览 113回答 1
1回答

慕村9548890

分析堆栈跟踪,看起来您正试图在此处分配一个太大的切片:db_template.XCludeList.getAllCombinationComplex()indexdb/db_template.XCludeList.getAllCombinationComplex(0xea4382c480, 0x8, 0x9, 0xe4ec1dc460, 0x4, 0x4, 0x0, 0x0, 0x0)    /home/scmbuild/workspaces_cluster/index/src/indexdb/db_template/db.go:145 +0x371 fp=0xea27f3ca88 sp=0xea27f3c900这称为runtime.makeslice():runtime.makeslice(0xa38840, 0x3ecc38680, 0x3ecc38680, 0x0, 0x0, 0x0)    /usr/local/go1.6.2/src/runtime/slice.go:32 +0x165 fp=0xea27f3c900 sp=0xea27f3c8b0Go 1.6的源代码runtime.makeslice()在这里:slice.go:func makeslice(t *slicetype, len64, cap64 int64) slice {    ...}它是用参数调用的:runtime.makeslice(0xa38840, 0x3ecc38680, 0x3ecc38680, 0x0, 0x0, 0x0)第二个值是长度,即0x3ecc38680 = 16857138816您试图创建一个包含超过 16*10 9 个元素的切片。如果切片的元素类型需要至少 1 个字节(不包括零大小的类型),则大约为 16 GB!这只是一个较低的估计。显然,在 8 GB 可用 RAM 的情况下,此操作无法成功。另外,请更新您的 Go,1.6.2 已经快 3 年了,不再受支持(甚至没有收到安全补丁)。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go