我已经开始介绍我的一些Go1.2代码,而顶级项目总是名为'etext'。我已经四处搜索但除了它可能与Go例程中的调用深度有关外,找不到有关它的更多信息。但是,我没有使用任何Go例程,'etext'仍占用总执行时间的75%或更多。
(pprof) top20
Total: 171 samples
128 74.9% 74.9% 128 74.9% etext
有人可以解释这是什么以及是否有办法减少影响?
答案 0 :(得分:3)
我遇到了同样的问题然后我发现了这个问题:pprof broken in go 1.2?。为了验证它确实是一个1.2 bug,我编写了以下“hello world”程序:
package main
import (
"fmt"
"testing"
)
func BenchmarkPrintln( t *testing.B ){
TestPrintln( nil )
}
func TestPrintln( t *testing.T ){
for i := 0; i < 10000; i++ {
fmt.Println("hello " + " world!")
}
}
如您所见,它只调用fmt.Println。
您可以使用“go test -c”进行编译。 使用“./test.test-test.bench”运行。 -test.cpuprofile = test.prof” 使用“go tool pprof test.test test.prof”
查看结果(pprof) top10
Total: 36 samples
18 50.0% 50.0% 18 50.0% syscall.Syscall
8 22.2% 72.2% 8 22.2% etext
4 11.1% 83.3% 4 11.1% runtime.usleep
3 8.3% 91.7% 3 8.3% runtime.futex
1 2.8% 94.4% 1 2.8% MHeap_AllocLocked
1 2.8% 97.2% 1 2.8% fmt.(*fmt).padString
1 2.8% 100.0% 1 2.8% os.epipecheck
0 0.0% 100.0% 1 2.8% MCentral_Grow
0 0.0% 100.0% 33 91.7% System
0 0.0% 100.0% 3 8.3% _/home/xxiao/work/test.BenchmarkPrintln
使用go 1.2.1获得上述结果 然后我使用go 1.1.1做了同样的事情并获得了以下结果:
(pprof) top10
Total: 10 samples
2 20.0% 20.0% 2 20.0% scanblock
1 10.0% 30.0% 1 10.0% fmt.(*pp).free
1 10.0% 40.0% 1 10.0% fmt.(*pp).printField
1 10.0% 50.0% 2 20.0% fmt.newPrinter
1 10.0% 60.0% 2 20.0% os.(*File).Write
1 10.0% 70.0% 1 10.0% runtime.MCache_Alloc
1 10.0% 80.0% 1 10.0% runtime.exitsyscall
1 10.0% 90.0% 1 10.0% sweepspan
1 10.0% 100.0% 1 10.0% sync.(*Mutex).Lock
0 0.0% 100.0% 6 60.0% _/home/xxiao/work/test.BenchmarkPrintln
您可以看到1.2.1结果没有多大意义。 Syscall和etext占用了大部分时间。并且1.1.1结果看起来正确。
所以我确信它确实是一个1.2.1错误。我在实际项目中切换到使用go 1.1.1,现在我对分析结果感到满意。
答案 1 :(得分:2)
我认为Mathias Urlichs在您的cgo代码中缺少调试符号是正确的。值得注意的是,像net和syscall这样的标准pkgs使用了cgo。
如果向下滚动到此doc的底部到名为Caveats的部分,您可以看到第三个项目说明......
如果程序链接在未编译足够符号信息的库中,则与库关联的所有样本可能会被收取到库中程序中找到的最后一个符号。这将人为地夸大该符号的计数。
我不是100%肯定这是正在发生的事情,但我打赌这就是为什么etext似乎如此繁忙(换句话说,etext是各种功能的集合,没有足够的信息用于pprof到分析得当。)