2015-06-16 81 views
2

我试图简要介绍一下golang应用程序,但我不能有工作,我按照这两个教程:无法获得golang pprof工作

两者都说在向应用程序添加一些代码行之后,您必须执行您的应用程序,我这样做了,并且在屏幕上收到以下消息:

2015年6月16日12点04分00秒的个人资料:CPU启用分析 /var/folders/kg/4fxym1sn0bx02zl_2sdbmrhr9wjvqt/T/profile680799962/cpu.pprof

所以,据我了解,分析是正在执行,发送信息到文件。

但是,当我看到文件大小时,在我测试的任何程序中,它始终是64字节。

当我尝试打开与pprof的cpu.pprof文件,我执行“TOP10”的命令,我看没有什么是文件中:

(“./fact”是我的应用程序)

去工具pprof ./fact /var/folders/kg/4fxym1sn0bx02zl_2sdbmrhr9wjvqt/T/profile680799962/cpu.pprof

TOP10 - >

(pprof)TOP10 0 0总的(0 %) flat flat%sum%cum cum%

所以,这就好像我在分析时没有任何事情发生。

我已经在mac(本例)和ubuntu中用三种不同的程序对它进行了测试。

你知道我做错了吗?

然后示例程序很简单,这是代码(是我从网上取一个非常简单的阶乘程序):

import "fmt" 
import "github.com/davecheney/profile" 

func fact(n int) int { 
     if n == 0 { 
     return 1 
     } 
     return n * fact(n-1) 
} 

func main() { 
     defer profile.Start(profile.CPUProfile).Stop() 
     fmt.Println(fact(30)) 
} 

感谢, 费尔

+2

首先,您使用的操作系统是什么?其次,'pprof'是一个“采样分析器”,你没有做任何可以抽样的事情。你的应用程序需要不断地执行指令以获得足够的时间来累积足够的样本(使用net/http/pprof时,默认样本时间为30秒) – JimB

+0

我正在使用OSX 10.10.2(Yosemite)。我现在正在尝试在长时间使用该配置文件工作,现在我看到该文件有更多的信息:)谢谢! – Fersca

+1

您还需要阅读以下内容:http://godoc.org/rsc.io/pprof_mac_fix – JimB

回答

4

的问题是,你的函数运行速度过快,并且pprof无法对其进行采样。尝试在fact调用周围添加一个循环,并对结果进行求和以人为延长程序。

+0

谢谢,我会尝试一下,我会告诉你结果! :) – Fersca

+0

我现在看到,在添加了{;;}和一个睡眠之后,该文件有更多信息。谢谢 :) – Fersca

5

正如已经提到的inf,你的代码执行得太快了。原因是pprof通过在执行过程中反复停止你的程序来工作,看看那个时刻哪个函数正在运行并写下来(和整个函数调用栈一起)。 Pprof样本的速率为每秒100个样本。这是在运行时/ pprof/pprof中硬编码的。去,你可以很容易地检查(见https://golang.org/src/runtime/pprof/pprof.go线575和它上面的注释):

func StartCPUProfile(w io.Writer) error { 
// The runtime routines allow a variable profiling rate, 
// but in practice operating systems cannot trigger signals 
// at more than about 500 Hz, and our processing of the 
// signal is not cheap (mostly getting the stack trace). 
// 100 Hz is a reasonable choice: it is frequent enough to 
// produce useful data, rare enough not to bog down the 
// system, and a nice round number to make it easy to 
// convert sample counts to seconds. Instead of requiring 
// each client to specify the frequency, we hard code it. 
const hz = 100 

// Avoid queueing behind StopCPUProfile. 
// Could use TryLock instead if we had it. 
if cpu.profiling { 
    return fmt.Errorf("cpu profiling already in use") 
} 

cpu.Lock() 
defer cpu.Unlock() 
if cpu.done == nil { 
    cpu.done = make(chan bool) 
} 
// Double-check. 
if cpu.profiling { 
    return fmt.Errorf("cpu profiling already in use") 
} 
cpu.profiling = true 
runtime.SetCPUProfileRate(hz) 
go profileWriter(w) 
return nil 

}

你的程序运行更多的样品可以制成,更可能会成为也越长短的运行功能将被采样。如果您的程序在完成第一个样本之前完成,那么生成的cpu.pprof将为空。

正如可以从上面的代码中看到,采样率被设定为

runtime.SetCPUProfileRate(..) 

如果之前与另一个值调用runtime.SetCPUProfileRate()调用StartCPUProfile(),则可以覆盖采样率。在程序执行期间,您会收到一条警告消息,告诉您“runtime:无法设置cpu配置文件速率,直到以前的配置文件完成。”你可以忽略。这是因为pprof.go再次调用SetCPUProfileRate()。由于您已经设置了该值,因此pprof中的值将被忽略。

另外,戴夫切尼发布了他的分析工具的新版本,你可以在这里找到它:https://github.com/pkg/profile。在那里,你可以,其他的变化中,指定的路径,其中cpu.pprof写到:

defer profile.Start(profile.CPUProfile, profile.ProfilePath(".")).Stop() 

你可以阅读一下:http://dave.cheney.net/2014/10/22/simple-profiling-package-moved-updated

顺便说一句,你的事实()函数将快速溢出,即使您将int64作为参数并返回值。 30!大约是2 * 10^32,int64存储的值只有2^63-1,大约是9 * 10^18。