- 全局常量与变量
- 方法
- Func">type Func
- Frame">type Frame
- Frames">type Frames
- MemStats">type MemStats
- BlockProfileRecord">type BlockProfileRecord
- StackRecord">type StackRecord
- MemProfileRecord">type MemProfileRecord
全局常量与变量
const GOOS string = theGoos 返回当前的操作系统const GOARCH string = theGoarch 返回当前处理器架构//内存profile记录器平均每分配MemProfileRate字节进行一次分配采样var MemProfileRate int = 512 * 1024
方法
func GOROOT() string GOROOT返回Go的根目录
func Version() string 返回Go的版本字符串
func NumCPU() int 返回本地机器的逻辑CPU个数
func GOMAXPROCS(n int) int 设置cpu执行数,默认为本机cpu数。当参数小于 1 时使用默认值
func GC() 执行一次垃圾回收
// 类似析构函数的意思,将x的终止器设置为f,在x被垃圾回收时调用f
func SetFinalizer(x, f interface{})
参数x必须是指针类型。参数f是一个函数,其参数就是x,并且没有返回值。当GC发现x不可达时,会在另一个独立的goroutine中执行f(x)。接着,GC会清除x的关联函数f。这样,x再次可达,但是没了关联函数。当下次GC发现obj不可达时,会释放obj。SetFinalizer只有在对象object被GC时,才会被执行。其他情况下,都不会被执行,即使程序正常结束或者发生错误。x的终止器会在x变为不可接触之后的任意时间被调度,不保证在程序退出之前执行package mainimport ("log""runtime""time")type Road intfunc findRoad(r *Road) {log.Println("road:", *r)}func entry(){var rd Road = Road(999)r := &rdruntime.SetFinalizer(r, findRoad)}func main(){entry()for i:=0; i < 10; i++ {time.Sleep(time.Second)runtime.GC()}}// 2019/02/07 17:27:07 road: 999
// KeepAlive将其参数标记为当前可达。这确保在程序中调用KeepAlive的点之前,不释放对象,也不运行它的finalizer
func KeepAlive(x interface{})
type File struct { d int }d, err := syscall.Open("/file/path", syscall.O_RDONLY, 0)// ... do something if err != nil ...p := &File{d}runtime.SetFinalizer(p, func(p *File) { syscall.Close(p.d) })var buf [10]byten, err := syscall.Read(p.d, buf[:])// Ensure p is not finalized until Read returns.runtime.KeepAlive(p)// No more uses of p after this point.
//Stack将调用其的go程的调用栈踪迹格式化后写入到buf中并返回写入的字节数
//若all为true,函数会在写入当前go程的踪迹信息后,将其它所有go程的调用栈踪迹都格式化写入到buf中
func Stack(buf []byte, all bool) int
//Caller报告当前go程调用栈所执行的函数的文件和行号信息
//实参skip为上溯的栈帧数,0表示Caller的调用者(Caller所在的调用栈)
//函数的返回值为调用栈标识符、文件名、该调用在文件中的行号
//如果无法获得信息,ok会被设为false
func Caller(skip int) (pc uintptr, file string, line int, ok bool)
package mainimport ("fmt""runtime")func a() {_, file, line, _ := runtime.Caller(0)fmt.Println(file, line)}func b() {}func main() {a()}/Users/mac/Desktop/go/commons/gintest/1.go 9
//函数把当前go程调用栈上的调用栈标识符填入切片pc中,返回写入到pc中的项数。
//实参skip为开始在pc中记录之前所要跳过的栈帧数,0表示Callers自身的调用栈(即最后一层是Callers所在的调用栈)。
func Callers(skip int, pc []uintptr) int
func fun() {var a = make([]uintptr, 10)fmt.Println(runtime.Callers(0, a)) // 5}func main() {fun()}
func NumCgoCall() int64 返回当前进程执行的cgo调用次数
func NumGoroutine() int 返回当前存在的Go程数
func Goexit() 退出当前 goroutine(但是defer语句会照常执行)
func Gosched() 让当前线程让出 cpu 以让其它线程运行,当前线程未来会继续执行
func LockOSThread() 将当前的go程绑定到当前所在的操作系统线程,其它go程则不能进入该线程
func UnlockOSThread() 线程解锁,如果没有绑定,不做任何操作
单核测试
func init() {runtime.GOMAXPROCS(1) //使用单核}func main() {exit := make(chan int)go func() {defer close(exit)go func() {fmt.Println("b")}()}()for i := 0; i < 4; i++ {fmt.Println("a:", i)if i == 1 {runtime.Gosched() //切换任务}}<-exit}//由于是单核模式,是并发的模式,其他协程只有等main让出cpu后才能运行a: 0a: 1ba: 2a: 3
多核测试
func main() {exit := make(chan int)go func() {defer close(exit)go func() {fmt.Println("b")}()}()for i := 0; i < 4; i++ {fmt.Println("a:", i)if i == 1 {runtime.Gosched() //切换任务}}<-exit}//会发现运行几次结果会存在不一样的问题//因为设置了多核,此时的任务是并行状态,不需要main让出cpu,其他的协程就可以运行a: 0ba: 1a: 2a: 3
type Func
type Func struct {// 内含隐藏或非导出字段}//FuncForPC返回一个表示调用栈标识符pc对应的调用栈的*Func//如果该调用栈标识符没有对应的调用栈,函数会返回nilfunc FuncForPC(pc uintptr) *Funcfunc (f *Func) Name() string 返回该调用栈所调用的函数的名字//FileLine返回该调用栈所调用的函数的源代码文件名和行号//如果pc不是f内的调用栈标识符,结果是不精确的func (f *Func) FileLine(pc uintptr) (file string, line int)func (f *Func) Entry() uintptr Entry返回该调用栈的调用栈标识符
type Frame
Frame是由Frames为每个调用帧返回的信息
type Frame struct {// PC是这个帧中位置的程序计数器。对于调用另一帧的帧,这将是调用指令的程序计数器。// 由于内联,多个帧可能具有相同的PC值,但不同的符号信息。PC uintptr// Func是这个调用帧的Func值Func *Func// Function == Func.Name().Function string// 文件名和行号File stringLine int// Entry point program counter for the function; may be zero// if not known. If Func is not nil then Entry ==// Func.Entry().Entry uintptr// contains filtered or unexported fields}
type Frames
type Frames struct {// contains filtered or unexported fields}func CallersFrames(callers []uintptr) *Framesfunc (ci *Frames) Next() (frame Frame, more bool)
package mainimport ("fmt""runtime""strings")func main() {c := func() {// Ask runtime.Callers for up to 10 pcs, including runtime.Callers itself.pc := make([]uintptr, 10)n := runtime.Callers(0, pc)if n == 0 {// No pcs available. Stop now.// This can happen if the first argument to runtime.Callers is large.return}pc = pc[:n] // pass only valid pcs to runtime.CallersFramesframes := runtime.CallersFrames(pc)// Loop to get frames.// A fixed number of pcs can expand to an indefinite number of Frames.for {frame, more := frames.Next()// To keep this example's output stable// even if there are changes in the testing package,// stop unwinding when we leave package runtime.if !strings.Contains(frame.File, "runtime/") {break}fmt.Printf("- more:%v | %s\n", more, frame.Function)if !more {break}}}b := func() { c() }a := func() { b() }a()}
type MemStats
MemStats记录内存申请和分配的统计信息。
type MemStats struct {// 已分配堆对象的字节数,同下面的HeapAllocAlloc uint64// 为堆对象分配的累积字节数,一直增加,对象被释放也不会减少TotalAlloc uint64// 从系统中获取的字节数(下面XxxSys之和)Sys uint64// 指针查找的次数Lookups uint64// 申请内存的次数Mallocs uint64// 释放内存的次数Frees uint64// 已分配堆对象的字节数// 包含所有可达,以及被GC标记为不可达但还没被清理的对象HeapAlloc uint64// 从系统中获取的字节数HeapSys uint64// 闲置span中的字节数HeapIdle uint64// 非闲置span中的字节数HeapInuse uint64// 释放到系统的字节数HeapReleased uint64// 已分配对象的总个数HeapObjects uint64// mspan 在使用的字节数MSpanInuse uint64// mspan 从系统中获得的字节数MSpanSys uint64// mcache 在使用的字节数MCacheInuse uint64// mcache 从系统中获得的字节数MCacheSys uint64// profile桶散列表BuckHashSys uint64// 垃圾收集元数据中的内存字节数GCSys uint64 // Go 1.2OtherSys uint64 // Go 1.2// 会在HeapAlloc字段到达该值(字节数)时运行下次GCNextGC uint64// 上次运行的绝对时间(纳秒)LastGC uint64// 由于GC 导致的STW总耗时(纳秒)PauseTotalNs uint64// 近期GC暂停时间的循环缓冲,最近一次在[(NumGC+255)%256]PauseNs [256]uint64// GC 开始时间循环缓冲,最近一次在[(NumGC+255)%256] = LastGCPauseEnd [256]uint64 // Go 1.4NumGC uint32NumForcedGC uint32 // Go 1.8GCCPUFraction float64 // Go 1.5EnableGC boolDebugGC boolBySize [61]struct {// Size is the maximum byte size of an object in this// size class.Size uint32// Mallocs is the cumulative count of heap objects// allocated in this size class. The cumulative bytes// of allocation is Size*Mallocs. The number of live// objects in this size class is Mallocs - Frees.Mallocs uint64// Frees is the cumulative count of heap objects freed// in this size class.Frees uint64}}func ReadMemStats(m *MemStats)
type BlockProfileRecord
BlockProfileRecord用于描述某个调用栈序列发生的阻塞事件的信息
type BlockProfileRecord struct {Count int64Cycles int64StackRecord}//SetBlockProfileRate控制阻塞profile记录go程阻塞事件的采样频率。//对于一个阻塞事件,平均每阻塞rate纳秒,阻塞profile记录器就采集一份样本。//要在profile中包括每一个阻塞事件,需传入rate=1;要完全关闭阻塞profile的记录,需传入rate<=0。func SetBlockProfileRate(rate int)//BlockProfile返回当前阻塞profile中的记录个数。//如果len(p)>=n,本函数就会将此profile中的记录复制到p中并返回(n, true)。//如果len(p)<n,本函数则不会修改p,而只返回(n, false)。//使用者应当使用runtime/pprof包或testing包的-test.blockprofile标记,而非直接调用 BlockProfile。func BlockProfile(p []BlockProfileRecord) (n int, ok bool)//MutexProfile 返回n,当前互斥锁配置文件中的记录数。//如果len(p) >= n, MutexProfile将该配置文件复制到p中,并返回n, true。//否则,MutexProfile不会更改p,并返回n, false//使用者应当使用runtime/pprof包,而不是直接调用MutexProfilefunc MutexProfile(p []BlockProfileRecord) (n int, ok bool)func SetMutexProfileFraction(rate int) intfunc SetBlockProfileRate(rate int)
type StackRecord
StackRecord描述单条调用栈
type StackRecord struct {Stack0 [32]uintptr // 该记录的调用栈踪迹,以第一个零值成员截止}// Stack返回与记录相关联的调用栈踪迹func (r *StackRecord) Stack() []uintptr//GoroutineProfile返回活跃go程的堆栈profile中的记录个数。//若len(p) >= n,函数就会将profile中的记录复制到p中并返回(n, true)。//若len(p) < n,则不会修改p,而只返回(n, false)。//绝大多数调用者应当使用runtime/pprof包,而非直接调用GoroutineProfile。func GoroutineProfile(p []StackRecord) (n int, ok bool)//返回线程创建profile中的记录个数。//如果len(p)>=n,本函数就会将profile中的记录复制到p中并返回(n, true)。//若len(p)<n,则不会更改p,而只返回(n, false)。//绝大多数使用者应当使用runtime/pprof包,而非直接调用ThreadCreateProfile。func ThreadCreateProfile(p []StackRecord) (n int, ok bool)
type MemProfileRecord
memprofilerrecord描述了由特定的调用序列(堆栈跟踪)分配的活动对象
type MemProfileRecord struct {AllocBytes, FreeBytes int64 // number of bytes allocated, freedAllocObjects, FreeObjects int64 // number of objects allocated, freedStack0 [32]uintptr // stack trace for this record; ends at first 0 entry}func (r *MemProfileRecord) InUseBytes() int64 AllocBytes - FreeBytesfunc (r *MemProfileRecord) InUseObjects() int64 AllocObjects - FreeObjectsfunc (r *MemProfileRecord) Stack() []uintptr Stack返回与该记录关联的堆栈跟踪//MemProfile返回每个分配站点分配和释放的内存的概要。//MemProfile返回当前内存配置文件中的记录数n。//如果len(p) >= n, MemProfile将该配置文件复制到p中,并返回n, true。//如果len(p) < n, MemProfile不改变p并返回n, false。//如果inuseZero为真,配置文件中包含r.AllocBytes > 0 但是r.AllocBytes == r.FreeBytes的分配记录。//这些站点分配了内存,但是内存都被释放回运行时。//绝大多数使用者应当使用runtime/pprof包,或-test.memprofile标记,而非直接调用MemProfilefunc MemProfile(p []MemProfileRecord, inuseZero bool) (n int, ok bool)
