尽量比避免内存开销
-
传递数组或者其他东西的时候,使用引用传递,而不是值传递
image.png
package gc_friendly
import (
"testing"
)
const NumOfElems = 1000
type Content struct {
Detail [10000]int
}
func withValue(arr [NumOfElems]Content) int {
// fmt.Println(&arr[2])
return 0
}
func withReference(arr *[NumOfElems]Content) int {
//b := *arr
// fmt.Println(&arr[2])
return 0
}
func TestFn(t *testing.T) {
var arr [NumOfElems]Content
//fmt.Println(&arr[2])
withValue(arr)
withReference(&arr)
}
func BenchmarkPassingArrayWithValue(b *testing.B) {
var arr [NumOfElems]Content
b.ResetTimer()
for i := 0; i < b.N; i++ {
withValue(arr)
}
b.StopTimer()
}
func BenchmarkPassingArrayWithRef(b *testing.B) {
var arr [NumOfElems]Content
b.ResetTimer()
for i := 0; i < b.N; i++ {
withReference(&arr)
}
b.StopTimer()
}
-
你可以使用 go 内置的一些工具,用于分析内存
-
使用 GC 日志,可以查看程序在运行时内存回收的日志
image.png
-
以上面的代码为例,使用 GODEBUG=gctrace=1 go test -bench=BenchmarkPassingArrayWithValue 可以分析该程序运行时的内存使用
-
使用 trace,可以用于查看比较全面的内存使用
image.png
-
依然以上面的代码为例,使用 go test -bench=BenchmarkPassingArrayWithRef -trace=trace_ref.out 可以生成调用信息
-
使用 go tool trace trace_ref.out 可以查看程序运行时的内存使用情况
-
当然,你也可以在代码中使用 trace 提供的 API 来做更加细致内存分析
初始化合适的切片大小

package gc_friendly
import "testing"
const numOfElems = 100000
const times = 1000
func TestAutoGrow(t *testing.T) {
for i := 0; i < times; i++ {
s := []int{}
for j := 0; j < numOfElems; j++ {
s = append(s, j)
}
}
}
func TestProperInit(t *testing.T) {
for i := 0; i < times; i++ {
s := make([]int, 0, 100000)
for j := 0; j < numOfElems; j++ {
s = append(s, j)
}
}
}
func TestOverSizeInit(t *testing.T) {
for i := 0; i < times; i++ {
s := make([]int, 0, 800000)
for j := 0; j < numOfElems; j++ {
s = append(s, j)
}
}
}
func BenchmarkAutoGrow(b *testing.B) {
for i := 0; i < b.N; i++ {
s := []int{}
for j := 0; j < numOfElems; j++ {
s = append(s, j)
}
}
}
func BenchmarkProperInit(b *testing.B) {
for i := 0; i < b.N; i++ {
s := make([]int, 0, numOfElems)
for j := 0; j < numOfElems; j++ {
s = append(s, j)
}
}
}
func BenchmarkOverSizeInit(b *testing.B) {
for i := 0; i < b.N; i++ {
s := make([]int, 0, numOfElems*8)
for j := 0; j < numOfElems; j++ {
s = append(s, j)
}
}
}
网友评论