全局常量与变量

  1. const GOOS string = theGoos 返回当前的操作系统
  2. const GOARCH string = theGoarch 返回当前处理器架构
  3. //内存profile记录器平均每分配MemProfileRate字节进行一次分配采样
  4. 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{})

  1. 参数x必须是指针类型。
  2. 参数f是一个函数,其参数就是x,并且没有返回值。
  3. GC发现x不可达时,会在另一个独立的goroutine中执行f(x)。
  4. 接着,GC会清除x的关联函数f。这样,x再次可达,但是没了关联函数。
  5. 当下次GC发现obj不可达时,会释放obj
  6. SetFinalizer只有在对象objectGC时,才会被执行。
  7. 其他情况下,都不会被执行,即使程序正常结束或者发生错误。
  8. x的终止器会在x变为不可接触之后的任意时间被调度,不保证在程序退出之前执行
  9. package main
  10. import (
  11. "log"
  12. "runtime"
  13. "time"
  14. )
  15. type Road int
  16. func findRoad(r *Road) {
  17. log.Println("road:", *r)
  18. }
  19. func entry(){
  20. var rd Road = Road(999)
  21. r := &rd
  22. runtime.SetFinalizer(r, findRoad)
  23. }
  24. func main(){
  25. entry()
  26. for i:=0; i < 10; i++ {
  27. time.Sleep(time.Second)
  28. runtime.GC()
  29. }
  30. }
  31. // 2019/02/07 17:27:07 road: 999

// KeepAlive将其参数标记为当前可达。这确保在程序中调用KeepAlive的点之前,不释放对象,也不运行它的finalizer
func KeepAlive(x interface{})

  1. type File struct { d int }
  2. d, err := syscall.Open("/file/path", syscall.O_RDONLY, 0)
  3. // ... do something if err != nil ...
  4. p := &File{d}
  5. runtime.SetFinalizer(p, func(p *File) { syscall.Close(p.d) })
  6. var buf [10]byte
  7. n, err := syscall.Read(p.d, buf[:])
  8. // Ensure p is not finalized until Read returns.
  9. runtime.KeepAlive(p)
  10. // 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)

  1. package main
  2. import (
  3. "fmt"
  4. "runtime"
  5. )
  6. func a() {
  7. _, file, line, _ := runtime.Caller(0)
  8. fmt.Println(file, line)
  9. }
  10. func b() {
  11. }
  12. func main() {
  13. a()
  14. }
  15. /Users/mac/Desktop/go/commons/gintest/1.go 9

//函数把当前go程调用栈上的调用栈标识符填入切片pc中,返回写入到pc中的项数。
//实参skip为开始在pc中记录之前所要跳过的栈帧数,0表示Callers自身的调用栈(即最后一层是Callers所在的调用栈)。
func Callers(skip int, pc []uintptr) int

  1. func fun() {
  2. var a = make([]uintptr, 10)
  3. fmt.Println(runtime.Callers(0, a)) // 5
  4. }
  5. func main() {
  6. fun()
  7. }

func NumCgoCall() int64 返回当前进程执行的cgo调用次数

func NumGoroutine() int 返回当前存在的Go程数

func Goexit() 退出当前 goroutine(但是defer语句会照常执行)

func Gosched() 让当前线程让出 cpu 以让其它线程运行,当前线程未来会继续执行

func LockOSThread() 将当前的go程绑定到当前所在的操作系统线程,其它go程则不能进入该线程

func UnlockOSThread() 线程解锁,如果没有绑定,不做任何操作
单核测试

  1. func init() {
  2. runtime.GOMAXPROCS(1) //使用单核
  3. }
  4. func main() {
  5. exit := make(chan int)
  6. go func() {
  7. defer close(exit)
  8. go func() {
  9. fmt.Println("b")
  10. }()
  11. }()
  12. for i := 0; i < 4; i++ {
  13. fmt.Println("a:", i)
  14. if i == 1 {
  15. runtime.Gosched() //切换任务
  16. }
  17. }
  18. <-exit
  19. }
  20. //由于是单核模式,是并发的模式,其他协程只有等main让出cpu后才能运行
  21. a: 0
  22. a: 1
  23. b
  24. a: 2
  25. a: 3

多核测试

  1. func main() {
  2. exit := make(chan int)
  3. go func() {
  4. defer close(exit)
  5. go func() {
  6. fmt.Println("b")
  7. }()
  8. }()
  9. for i := 0; i < 4; i++ {
  10. fmt.Println("a:", i)
  11. if i == 1 {
  12. runtime.Gosched() //切换任务
  13. }
  14. }
  15. <-exit
  16. }
  17. //会发现运行几次结果会存在不一样的问题
  18. //因为设置了多核,此时的任务是并行状态,不需要main让出cpu,其他的协程就可以运行
  19. a: 0
  20. b
  21. a: 1
  22. a: 2
  23. a: 3

type Func

  1. type Func struct {
  2. // 内含隐藏或非导出字段
  3. }
  4. //FuncForPC返回一个表示调用栈标识符pc对应的调用栈的*Func
  5. //如果该调用栈标识符没有对应的调用栈,函数会返回nil
  6. func FuncForPC(pc uintptr) *Func
  7. func (f *Func) Name() string 返回该调用栈所调用的函数的名字
  8. //FileLine返回该调用栈所调用的函数的源代码文件名和行号
  9. //如果pc不是f内的调用栈标识符,结果是不精确的
  10. func (f *Func) FileLine(pc uintptr) (file string, line int)
  11. func (f *Func) Entry() uintptr Entry返回该调用栈的调用栈标识符

type Frame

Frame是由Frames为每个调用帧返回的信息

  1. type Frame struct {
  2. // PC是这个帧中位置的程序计数器。对于调用另一帧的帧,这将是调用指令的程序计数器。
  3. // 由于内联,多个帧可能具有相同的PC值,但不同的符号信息。
  4. PC uintptr
  5. // Func是这个调用帧的Func值
  6. Func *Func
  7. // Function == Func.Name().
  8. Function string
  9. // 文件名和行号
  10. File string
  11. Line int
  12. // Entry point program counter for the function; may be zero
  13. // if not known. If Func is not nil then Entry ==
  14. // Func.Entry().
  15. Entry uintptr
  16. // contains filtered or unexported fields
  17. }

type Frames

  1. type Frames struct {
  2. // contains filtered or unexported fields
  3. }
  4. func CallersFrames(callers []uintptr) *Frames
  5. func (ci *Frames) Next() (frame Frame, more bool)
  1. package main
  2. import (
  3. "fmt"
  4. "runtime"
  5. "strings"
  6. )
  7. func main() {
  8. c := func() {
  9. // Ask runtime.Callers for up to 10 pcs, including runtime.Callers itself.
  10. pc := make([]uintptr, 10)
  11. n := runtime.Callers(0, pc)
  12. if n == 0 {
  13. // No pcs available. Stop now.
  14. // This can happen if the first argument to runtime.Callers is large.
  15. return
  16. }
  17. pc = pc[:n] // pass only valid pcs to runtime.CallersFrames
  18. frames := runtime.CallersFrames(pc)
  19. // Loop to get frames.
  20. // A fixed number of pcs can expand to an indefinite number of Frames.
  21. for {
  22. frame, more := frames.Next()
  23. // To keep this example's output stable
  24. // even if there are changes in the testing package,
  25. // stop unwinding when we leave package runtime.
  26. if !strings.Contains(frame.File, "runtime/") {
  27. break
  28. }
  29. fmt.Printf("- more:%v | %s\n", more, frame.Function)
  30. if !more {
  31. break
  32. }
  33. }
  34. }
  35. b := func() { c() }
  36. a := func() { b() }
  37. a()
  38. }

type MemStats

MemStats记录内存申请和分配的统计信息。

  1. type MemStats struct {
  2. // 已分配堆对象的字节数,同下面的HeapAlloc
  3. Alloc uint64
  4. // 为堆对象分配的累积字节数,一直增加,对象被释放也不会减少
  5. TotalAlloc uint64
  6. // 从系统中获取的字节数(下面XxxSys之和)
  7. Sys uint64
  8. // 指针查找的次数
  9. Lookups uint64
  10. // 申请内存的次数
  11. Mallocs uint64
  12. // 释放内存的次数
  13. Frees uint64
  14. // 已分配堆对象的字节数
  15. // 包含所有可达,以及被GC标记为不可达但还没被清理的对象
  16. HeapAlloc uint64
  17. // 从系统中获取的字节数
  18. HeapSys uint64
  19. // 闲置span中的字节数
  20. HeapIdle uint64
  21. // 非闲置span中的字节数
  22. HeapInuse uint64
  23. // 释放到系统的字节数
  24. HeapReleased uint64
  25. // 已分配对象的总个数
  26. HeapObjects uint64
  27. // mspan 在使用的字节数
  28. MSpanInuse uint64
  29. // mspan 从系统中获得的字节数
  30. MSpanSys uint64
  31. // mcache 在使用的字节数
  32. MCacheInuse uint64
  33. // mcache 从系统中获得的字节数
  34. MCacheSys uint64
  35. // profile桶散列表
  36. BuckHashSys uint64
  37. // 垃圾收集元数据中的内存字节数
  38. GCSys uint64 // Go 1.2
  39. OtherSys uint64 // Go 1.2
  40. // 会在HeapAlloc字段到达该值(字节数)时运行下次GC
  41. NextGC uint64
  42. // 上次运行的绝对时间(纳秒)
  43. LastGC uint64
  44. // 由于GC 导致的STW总耗时(纳秒)
  45. PauseTotalNs uint64
  46. // 近期GC暂停时间的循环缓冲,最近一次在[(NumGC+255)%256]
  47. PauseNs [256]uint64
  48. // GC 开始时间循环缓冲,最近一次在[(NumGC+255)%256] = LastGC
  49. PauseEnd [256]uint64 // Go 1.4
  50. NumGC uint32
  51. NumForcedGC uint32 // Go 1.8
  52. GCCPUFraction float64 // Go 1.5
  53. EnableGC bool
  54. DebugGC bool
  55. BySize [61]struct {
  56. // Size is the maximum byte size of an object in this
  57. // size class.
  58. Size uint32
  59. // Mallocs is the cumulative count of heap objects
  60. // allocated in this size class. The cumulative bytes
  61. // of allocation is Size*Mallocs. The number of live
  62. // objects in this size class is Mallocs - Frees.
  63. Mallocs uint64
  64. // Frees is the cumulative count of heap objects freed
  65. // in this size class.
  66. Frees uint64
  67. }
  68. }
  69. func ReadMemStats(m *MemStats)

type BlockProfileRecord

BlockProfileRecord用于描述某个调用栈序列发生的阻塞事件的信息

  1. type BlockProfileRecord struct {
  2. Count int64
  3. Cycles int64
  4. StackRecord
  5. }
  6. //SetBlockProfileRate控制阻塞profile记录go程阻塞事件的采样频率。
  7. //对于一个阻塞事件,平均每阻塞rate纳秒,阻塞profile记录器就采集一份样本。
  8. //要在profile中包括每一个阻塞事件,需传入rate=1;要完全关闭阻塞profile的记录,需传入rate<=0。
  9. func SetBlockProfileRate(rate int)
  10. //BlockProfile返回当前阻塞profile中的记录个数。
  11. //如果len(p)>=n,本函数就会将此profile中的记录复制到p中并返回(n, true)。
  12. //如果len(p)<n,本函数则不会修改p,而只返回(n, false)。
  13. //使用者应当使用runtime/pprof包或testing包的-test.blockprofile标记,而非直接调用 BlockProfile。
  14. func BlockProfile(p []BlockProfileRecord) (n int, ok bool)
  15. //MutexProfile 返回n,当前互斥锁配置文件中的记录数。
  16. //如果len(p) >= n, MutexProfile将该配置文件复制到p中,并返回n, true。
  17. //否则,MutexProfile不会更改p,并返回n, false
  18. //使用者应当使用runtime/pprof包,而不是直接调用MutexProfile
  19. func MutexProfile(p []BlockProfileRecord) (n int, ok bool)
  20. func SetMutexProfileFraction(rate int) int
  21. func SetBlockProfileRate(rate int)

type StackRecord

StackRecord描述单条调用栈

  1. type StackRecord struct {
  2. Stack0 [32]uintptr // 该记录的调用栈踪迹,以第一个零值成员截止
  3. }
  4. // Stack返回与记录相关联的调用栈踪迹
  5. func (r *StackRecord) Stack() []uintptr
  6. //GoroutineProfile返回活跃go程的堆栈profile中的记录个数。
  7. //若len(p) >= n,函数就会将profile中的记录复制到p中并返回(n, true)。
  8. //若len(p) < n,则不会修改p,而只返回(n, false)。
  9. //绝大多数调用者应当使用runtime/pprof包,而非直接调用GoroutineProfile。
  10. func GoroutineProfile(p []StackRecord) (n int, ok bool)
  11. //返回线程创建profile中的记录个数。
  12. //如果len(p)>=n,本函数就会将profile中的记录复制到p中并返回(n, true)。
  13. //若len(p)<n,则不会更改p,而只返回(n, false)。
  14. //绝大多数使用者应当使用runtime/pprof包,而非直接调用ThreadCreateProfile。
  15. func ThreadCreateProfile(p []StackRecord) (n int, ok bool)

type MemProfileRecord

memprofilerrecord描述了由特定的调用序列(堆栈跟踪)分配的活动对象

  1. type MemProfileRecord struct {
  2. AllocBytes, FreeBytes int64 // number of bytes allocated, freed
  3. AllocObjects, FreeObjects int64 // number of objects allocated, freed
  4. Stack0 [32]uintptr // stack trace for this record; ends at first 0 entry
  5. }
  6. func (r *MemProfileRecord) InUseBytes() int64 AllocBytes - FreeBytes
  7. func (r *MemProfileRecord) InUseObjects() int64 AllocObjects - FreeObjects
  8. func (r *MemProfileRecord) Stack() []uintptr Stack返回与该记录关联的堆栈跟踪
  9. //MemProfile返回每个分配站点分配和释放的内存的概要。
  10. //MemProfile返回当前内存配置文件中的记录数n。
  11. //如果len(p) >= n, MemProfile将该配置文件复制到p中,并返回n, true。
  12. //如果len(p) < n, MemProfile不改变p并返回n, false。
  13. //如果inuseZero为真,配置文件中包含r.AllocBytes > 0 但是r.AllocBytes == r.FreeBytes的分配记录。
  14. //这些站点分配了内存,但是内存都被释放回运行时。
  15. //绝大多数使用者应当使用runtime/pprof包,或-test.memprofile标记,而非直接调用MemProfile
  16. func MemProfile(p []MemProfileRecord, inuseZero bool) (n int, ok bool)