我正在运行caching project I contribute to的基准测试,并且基准测试继续运行失败,因为在为并行基准测试初始化新的缓存分片时无法分配虚拟内存。
github.com\mxplusb\bigcache\caches_bench> go test -v -bench "." -benchtime "10s" . -timeout 30m
-benchmem
BenchmarkMapSet-8 20000000 917 ns/op 296 B/op 3 allocs/op
BenchmarkFreeCacheSet-8 30000000 861 ns/op 360 B/op 3 allocs/op
BenchmarkBigCacheSet-8 30000000 615 ns/op 311 B/op 2 allocs/op
BenchmarkMapGet-8 50000000 410 ns/op 24 B/op 2 allocs/op
BenchmarkFreeCacheGet-8 30000000 770 ns/op 152 B/op 4 allocs/op
BenchmarkBigCacheGet-8 30000000 548 ns/op 152 B/op 4 allocs/op
BenchmarkBigCacheSetParallel-8 runtime: VirtualAlloc of 7340032 bytes failed with errno=1455
fatal error: runtime: cannot map pages in arena address space
runtime stack:
runtime.throw(0x55ca82, 0x30)
C:/Go/src/runtime/panic.go:596 +0x9c
runtime.sysMap(0xc4fc330000, 0x700000, 0x428e01, 0x6152f8)
C:/Go/src/runtime/mem_windows.go:116 +0x129
runtime.(*mheap).sysAlloc(0x5fb5c0, 0x700000, 0x419fd70)
C:/Go/src/runtime/malloc.go:440 +0x37b
runtime.(*mheap).grow(0x5fb5c0, 0x380, 0x0)
C:/Go/src/runtime/mheap.go:774 +0x69
runtime.(*mheap).allocSpanLocked(0x5fb5c0, 0x380, 0x874ca20)
C:/Go/src/runtime/mheap.go:678 +0x456
runtime.(*mheap).alloc_m(0x5fb5c0, 0x380, 0x100000000, 0x0)
C:/Go/src/runtime/mheap.go:562 +0xf0
runtime.(*mheap).alloc.func1()
C:/Go/src/runtime/mheap.go:627 +0x52
runtime.systemstack(0x419fe68)
C:/Go/src/runtime/asm_amd64.s:343 +0xb5
runtime.(*mheap).alloc(0x5fb5c0, 0x380, 0x10100000000, 0x0)
C:/Go/src/runtime/mheap.go:628 +0xa7
runtime.largeAlloc(0x700000, 0x44fd01, 0xc4f61be000)
C:/Go/src/runtime/malloc.go:807 +0x9a
runtime.mallocgc.func1()
C:/Go/src/runtime/malloc.go:702 +0x45
runtime.systemstack(0xc0420278a0)
C:/Go/src/runtime/asm_amd64.s:327 +0x7e
runtime.mstart()
C:/Go/src/runtime/proc.go:1132
goroutine 31 [running]:
runtime.systemstack_switch()
C:/Go/src/runtime/asm_amd64.s:281 fp=0xc042555980 sp=0xc042555978
runtime.mallocgc(0x700000, 0x53c400, 0x1, 0xc042031800)
C:/Go/src/runtime/malloc.go:703 +0x96f fp=0xc042555a20 sp=0xc042555980
runtime.newarray(0x53c400, 0x10000, 0x522b20)
C:/Go/src/runtime/malloc.go:833 +0x6b fp=0xc042555a60 sp=0xc042555a20
runtime.makemap(0x52d8a0, 0x5f5e1, 0x0, 0x0, 0x112)
C:/Go/src/runtime/hashmap.go:281 +0x30d fp=0xc042555ab8 sp=0xc042555a60
github.com/allegro/bigcache.initNewShard(0x100, 0x8bb2c97000, 0x5f5e100, 0x100, 0x1, 0x5e1820, 0x612938, 0x0, 0x0, 0xc0423fa000, ...)
E:/Programming/Go/src/github.com/allegro/bigcache/shard.go:45 +0xc5 fp=0xc042555c80 sp=0xc042555ab8
github.com/allegro/bigcache.newBigCache(0x100, 0x8bb2c97000, 0x5f5e100, 0x100, 0x1, 0x5e1820, 0x612938, 0x0, 0x0, 0x5e1560, ...)
E:/Programming/Go/src/github.com/allegro/bigcache/bigcache.go:58 +0x36e fp=0xc042555dc8 sp=0xc042555c80
github.com/allegro/bigcache.NewBigCache(0x100, 0x8bb2c97000, 0x5f5e100, 0x100, 0x1, 0x0, 0x0, 0x0, 0x0, 0xbc02a, ...)
E:/Programming/Go/src/github.com/allegro/bigcache/bigcache.go:27 +0x7f fp=0xc042555e48 sp=0xc042555dc8
github.com/mxplusb/bigcache/caches_bench.initBigCache(0x5f5e100, 0x4b6af8)
E:/Programming/Go/src/github.com/mxplusb/bigcache/caches_bench/caches_bench_test.go:159 +0x99 fp=0xc042555f00 sp=0xc042555e48
github.com/mxplusb/bigcache/caches_bench.BenchmarkBigCacheSetParallel(0xc042088420)
E:/Programming/Go/src/github.com/mxplusb/bigcache/caches_bench/caches_bench_test.go:79 +0x3d fp=0xc042555f38 sp=0xc042555f00
testing.(*B).runN(0xc042088420, 0x5f5e100)
C:/Go/src/testing/benchmark.go:140 +0xb9 fp=0xc042555f78 sp=0xc042555f38
testing.(*B).launch(0xc042088420)
C:/Go/src/testing/benchmark.go:281 +0x129 fp=0xc042555fd8 sp=0xc042555f78
runtime.goexit()
C:/Go/src/runtime/asm_amd64.s:2197 +0x1 fp=0xc042555fe0 sp=0xc042555fd8
created by testing.(*B).doBench
C:/Go/src/testing/benchmark.go:250 +0x77
goroutine 1 [chan receive]:
testing.(*B).doBench(0xc042088420, 0x0, 0x0, 0x0, 0x0, 0x0)
C:/Go/src/testing/benchmark.go:251 +0xa1
testing.(*benchContext).processBench(0xc0420030e0, 0xc042088420)
C:/Go/src/testing/benchmark.go:433 +0x1fe
testing.(*B).run(0xc042088420, 0x0, 0x0, 0x0, 0x0, 0x0)
C:/Go/src/testing/benchmark.go:241 +0x74
testing.(*B).Run(0xc0420882c0, 0x5593df, 0x1c, 0x55dc98, 0x4b6a00)
C:/Go/src/testing/benchmark.go:494 +0x254
testing.runBenchmarks.func1(0xc0420882c0)
C:/Go/src/testing/benchmark.go:403 +0x6e
testing.(*B).runN(0xc0420882c0, 0x1)
C:/Go/src/testing/benchmark.go:140 +0xb9
testing.runBenchmarks(0xc0420030c0, 0x5f6240, 0xa, 0xa, 0xc042040100)
C:/Go/src/testing/benchmark.go:409 +0x494
testing.(*M).Run(0xc042097f20, 0xc042039f20)
C:/Go/src/testing/testing.go:828 +0x30c
main.main()
github.com/mxplusb/bigcache/caches_bench/_test/_testmain.go:60 +0xfe
exit status 2
FAIL github.com/mxplusb/bigcache/caches_bench 223.732s
这是一台64位Windows 10计算机,具有32GB可用内存。当前页面文件存储在M.2 NVMe上,大约为5GB(系统管理)。从分片中为基准分配的特定内存量会有所不同,但通常在7-10MB之间。机器上的资源使用率很低,因此有大量可用资源。我知道这是一个页面文件问题,因为VirtualAlloc会在页面上保留内存。
新的缓存分片会保留这样的内存:
func initNewShard(config Config, callback onRemoveCallback) *cacheShard {
return &cacheShard{
hashmap: make(map[uint64]uint32, config.initialShardSize()),
entries: *queue.NewBytesQueue(config.initialShardSize()*config.MaxEntrySize, config.maximumShardSize(), config.Verbose),
entryBuffer: make([]byte, config.MaxEntrySize+headersSizeInBytes),
onRemove: callback,
}
}
它特别是在hashmap分配上失败了。 config.initialShardSize()
设置分片大小:
func (c Config) initialShardSize() int {
return max(c.MaxEntriesInWindow/c.Shards, minimumEntriesInShard)
}
当测试完成设置步骤时,它会像这样创建一个新的分片:
func initNewShard(config Config, callback onRemoveCallback) *cacheShard {
return &cacheShard{
hashmap: make(map[uint64]uint32, config.initialShardSize()),
entries: *queue.NewBytesQueue(config.initialShardSize()*config.MaxEntrySize, config.maximumShardSize(), config.Verbose),
entryBuffer: make([]byte, config.MaxEntrySize+headersSizeInBytes),
onRemove: callback,
}
}
我已经诊断出最初的问题,我知道这是VirtualAlloc内存预留的一个问题,但我不确定如何进一步排除故障并对问题进行分类。
我可以使用哪些其他配置/设置/工具来进一步解决此问题?