你好!以下是你要翻译的内容: 如何在Go单元测试中限制/控制内存使用?

huangapple go评论85阅读模式
英文:

How can i limit/gate memory usage in go unit test

问题

在Golang中,有没有办法在单元测试期间限制内存使用/增长的量?

例如,在Java中,我们可以这样做:

long before = Runtime.getRuntime().freeMemory();

// 分配一大堆内存
long after = Runtime.getRuntime().freeMemory();

Assert.AssertTrue(before - after < 100);

(大致上)来断言我们没有使用超过100字节的内存。

英文:

Is there a way to limit the amount of memory usage/growth during a unit test in golang?

For example, in java, we can do:

long before = Runtime.getRuntime().freeMemory()

// allocate a bunch of memory
long after = Runtime.getRuntime().freeMemory()

Assert.AssertTrue(before-after &lt; 100)

(roughly) to assert that we didn't use more than 100 bytes.

答案1

得分: 5

使用Go基准测试来分析内存使用情况。例如:

mem.go:

package mem

func memUse() {
	var stack [1024]byte
	heap := make([]byte, 64*1024)
	_, _ = stack, heap
}

mem_test.go:

package mem

import "testing"

func BenchmarkMemUse(b *testing.B) {
	b.ReportAllocs()
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		memUse()
	}
	b.StopTimer()
}

输出:

$ go test -bench=.
goos: linux
goarch: amd64
pkg: mem
BenchmarkMemUse-4  	  200000      8188 ns/op	   65536 B/op       1 allocs/op
PASS
ok  	mem	1.745s

memUse函数进行了一次分配大小为65536(64*1024)字节的堆内存分配。堆栈分配是廉价的,并且局部于函数,因此我们不计算它们。

除了使用ReportAllocs方法外,您还可以使用-benchmem标志。例如:

go test -bench=. -benchmem

参考资料:

Go: Package testing: Benchmarks

Command go: Description of testing functions

Command go: Description of testing flags


如果您确实需要在Go testing包的测试函数中应用内存限制,请尝试使用runtime.MemStats。例如:

func TestMemUse(t *testing.T) {
	defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(1))
	var start, end runtime.MemStats
	runtime.GC()
	runtime.ReadMemStats(&start)
	memUse()
	runtime.ReadMemStats(&end)
	alloc := end.TotalAlloc - start.TotalAlloc
	limit := uint64(64 * 1000)
	if alloc > limit {
		t.Error("memUse:", "allocated", alloc, "limit", limit)
	}
}

输出:

$ go test
--- FAIL: TestMemUse (0.00s)
	mem_test.go:18: memUse: allocated 65536 limit 64000
FAIL
exit status 1
FAIL	mem	0.003s
英文:

Use Go benchmarks to analyze memory usage. For example:

mem.go:

package mem

func memUse() {
	var stack [1024]byte
	heap := make([]byte, 64*1024)
	_, _ = stack, heap
}

mem_test.go:

package mem

import &quot;testing&quot;

func BenchmarkMemUse(b *testing.B) {
	b.ReportAllocs()
	b.ResetTimer()
	for i := 0; i &lt; b.N; i++ {
		memUse()
	}
	b.StopTimer()
}

Output:

$ go test -bench=.
goos: linux
goarch: amd64
pkg: mem
BenchmarkMemUse-4  	  200000      8188 ns/op	   65536 B/op       1 allocs/op
PASS
ok  	mem	1.745s

The memUse function makes one heap allocation of 65536 (64*1024) bytes. Stack allocations are cheap and local to a function so we don't count them.

Instead of the ReportAllocs method you could use the -benchmem flag. For example,

go test -bench=. -benchmem

References:

Go: Package testing: Benchmarks

Command go: Description of testing functions

Command go: Description of testing flags


If you really must apply a memory limit during a Go testing package Test function, try using runtime.MemStats. For example,

func TestMemUse(t *testing.T) {
	defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(1))
	var start, end runtime.MemStats
	runtime.GC()
	runtime.ReadMemStats(&amp;start)
	memUse()
	runtime.ReadMemStats(&amp;end)
	alloc := end.TotalAlloc - start.TotalAlloc
	limit := uint64(64 * 1000)
	if alloc &gt; limit {
		t.Error(&quot;memUse:&quot;, &quot;allocated&quot;, alloc, &quot;limit&quot;, limit)
	}
}

Output:

$ go test
--- FAIL: TestMemUse (0.00s)
	mem_test.go:18: memUse: allocated 65536 limit 64000
FAIL
exit status 1
FAIL	mem	0.003s

huangapple
  • 本文由 发表于 2017年2月21日 04:45:15
  • 转载请务必保留本文链接:https://go.coder-hub.com/42353883.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定