英文:
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 < 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 "testing"
func BenchmarkMemUse(b *testing.B) {
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < 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(&start)
memUse()
runtime.ReadMemStats(&end)
alloc := end.TotalAlloc - start.TotalAlloc
limit := uint64(64 * 1000)
if alloc > limit {
t.Error("memUse:", "allocated", alloc, "limit", 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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论