当前位置: 首页 > news >正文

制作网站服务wordpress media

制作网站服务,wordpress media,app运营成本估算,洛阳凯锦腾网业有限公司以下内容#xff0c;是对 运行时 runtime的神奇用法[1] 的学习与记录 目录: 1.获取GOROOT环境变量 2.获取GO的版本号 3.获取本机CPU个数 4.设置最大可同时执行的最大CPU数 5.设置cup profile 记录的速录 6.查看cup profile 下一次堆栈跟踪数据 7.立即执行一次垃圾回收 8.给变量… 以下内容是对 运行时 runtime的神奇用法[1] 的学习与记录 目录: 1.获取GOROOT环境变量 2.获取GO的版本号 3.获取本机CPU个数 4.设置最大可同时执行的最大CPU数 5.设置cup profile 记录的速录 6.查看cup profile 下一次堆栈跟踪数据 7.立即执行一次垃圾回收 8.给变量绑定方法,当垃圾回收的时候进行监听 9.查看内存申请和分配统计信息 10.查看程序正在使用的字节数 11.查看程序正在使用的对象数 12.获取调用堆栈列表 13.获取内存profile记录历史 14.执行一个断点 15.获取程序调用go协程的栈踪迹历史 16.获取当前函数或者上层函数的标识号、文件名、调用方法在当前文件中的行号 17.获取与当前堆栈记录相关链的调用栈踪迹 18.获取一个标识调用栈标识符pc对应的调用栈 19.获取调用栈所调用的函数的名字 20.获取调用栈所调用的函数的所在的源文件名和行号 21.获取该调用栈的调用栈标识符 22.获取当前进程执行的cgo调用次数 23.获取当前存在的go协程数 24.终止掉当前的go协程 25.让其他go协程优先执行,等其他协程执行完后,在执行当前的协程 26.获取活跃的go协程的堆栈profile以及记录个数 27.将调用的go协程绑定到当前所在的操作系统线程其它go协程不能进入该线程 28.解除go协程与操作系统线程的绑定关系 29.获取线程创建profile中的记录个数 30.控制阻塞profile记录go协程阻塞事件的采样率 31.返回当前阻塞profile中的记录个数 1. GOROOT()获取GOROOT环境变量 GOROOT() 返回Go的根目录。如果存在GOROOT环境变量返回该变量的值否则返回创建Go时的根目录 package mainimport ( fmt runtime)func main() { fmt.Println(runtime.GOROOT()) // /Users/fliter/.g/go} 2. Version() 获取GO的版本号 Version() 返回Go的版本字符串。要么是提交的hash和创建时的日期要么是发行标签如go1.20 package mainimport ( fmt runtime)func main() { fmt.Println(runtime.Version()) // go1.19} 3. NumCPU() 获取本机CPU个数 NumCPU返回本地机器的逻辑CPU个数 package mainimport ( fmt runtime)func main() { fmt.Println(runtime.NumCPU()) // 8} 4. GOMAXPROCS() 设置最大可同时执行的最大CPU数 GOMAXPROCS() 设置可同时执行的最大CPU数并返回先前的设置。 若 n 1则不会更改当前设置。 本地机器的逻辑CPU数可通过 NumCPU 查询。该函数在调度程序优化后会去掉?啥时候.. package mainimport ( fmt runtime time)func main() { runtime.GOMAXPROCS(1) startTime : time.Now() var s1 chan int64  make(chan int64) var s2 chan int64  make(chan int64) var s3 chan int64  make(chan int64) var s4 chan int64  make(chan int64) go calc(s1) go calc(s2) go calc(s3) go calc(s4) -s1 -s2 -s3 -s4 endTime : time.Now() fmt.Println(endTime.Sub(startTime)) // 第一行注释掉 耗时: 386.954625ms 取消注释 耗时: 1.34715s}func calc(s chan int64) { var count int64  0 for i : 0; i  1000000000; i {  count  int64(i) } s - count} 5. SetCPUProfileRate() 设置cup profile 记录的速录 SetCPUProfileRate() 设置CPU profile记录的速率为平均每秒hz次。如果hz0SetCPUProfileRate会关闭profile的记录。如果记录器在执行该速率必须在关闭之后才能修改 绝大多数使用者应使用runtime/pprof包或testing包的-test.cpuprofile选项而非直接使用SetCPUProfileRate 6. CPUProfile 查看cup profile 下一次堆栈跟踪数据 func CPUProfile() []byte 已废弃 7. GC() 立即执行一次垃圾回收 Go三种触发GC的方式之一 (另外两种为2分钟固定一次 达到阈值时触发) package mainimport ( runtime time)type Student struct { name string}func main() { var i *Student  new(Student) runtime.SetFinalizer(i, func(i interface{}) {  println(垃圾回收了) // 垃圾回收了 }) runtime.GC() // 如果将这行注释则上面不会输出 time.Sleep(time.Second)} 8. SetFinalizer() 给变量绑定方法,当垃圾回收的时候进行监听 func SetFinalizer(x, f interface{}) 注意x必须是指针类型,f 函数的参数一定要和x保持一致,或者写interface{},不然程序会报错 代码同上例 9. ReadMemStats() 查看内存申请和分配统计信息 可以获得如下信息: type MemStats struct {    // 一般统计    Alloc      uint64 // 已申请且仍在使用的字节数    TotalAlloc uint64 // 已申请的总字节数已释放的部分也算在内    Sys        uint64 // 从系统中获取的字节数下面XxxSys之和    Lookups    uint64 // 指针查找的次数    Mallocs    uint64 // 申请内存的次数    Frees      uint64 // 释放内存的次数    // 主分配堆统计    HeapAlloc    uint64 // 已申请且仍在使用的字节数    HeapSys      uint64 // 从系统中获取的字节数    HeapIdle     uint64 // 闲置span中的字节数    HeapInuse    uint64 // 非闲置span中的字节数    HeapReleased uint64 // 释放到系统的字节数    HeapObjects  uint64 // 已分配对象的总个数    // L低层次、大小固定的结构体分配器统计Inuse为正在使用的字节数Sys为从系统获取的字节数    StackInuse  uint64 // 引导程序的堆栈    StackSys    uint64    MSpanInuse  uint64 // mspan结构体    MSpanSys    uint64    MCacheInuse uint64 // mcache结构体    MCacheSys   uint64    BuckHashSys uint64 // profile桶散列表    GCSys       uint64 // GC元数据    OtherSys    uint64 // 其他系统申请    // 垃圾收集器统计    NextGC       uint64 // 会在HeapAlloc字段到达该值字节数时运行下次GC    LastGC       uint64 // 上次运行的绝对时间纳秒    PauseTotalNs uint64    PauseNs      [256]uint64 // 近期GC暂停时间的循环缓冲最近一次在[(NumGC255)%256]    NumGC        uint32    EnableGC     bool    DebugGC      bool    // 每次申请的字节数的统计61是C代码中的尺寸分级数    BySize [61]struct {        Size    uint32        Mallocs uint64        Frees   uint64    }} package mainimport ( fmt runtime time)type Student2 struct { name string}func main() { var list  make([]*Student2, 0) for i : 0; i  100000; i {  var s *Student2  new(Student2)  list  append(list, s) } memStatus : runtime.MemStats{} runtime.ReadMemStats(memStatus) fmt.Printf(申请的内存:%d\n, memStatus.Mallocs) // 申请的内存:100250 fmt.Printf(释放的内存次数:%d\n, memStatus.Frees) // 释放的内存次数:45 time.Sleep(time.Second)} 10. InUseBytes() 查看程序正在使用的字节数 func (r *MemProfileRecord) InUseBytes() int64 InUseBytes 返回正在使用的字节数AllocBytes – FreeBytes 11. InUseObjects() 查看程序正在使用的对象数 func (r *MemProfileRecord) InUseObjects() int64 InUseObjects 返回正在使用的对象数AllocObjects - FreeObjects 12. Stack() 获取调用堆栈列表 func (r *MemProfileRecord) Stack() []uintptr Stack返回关联至此记录的调用栈踪迹即r.Stack0的前缀 13. MemProfile() 获取内存profile记录历史 func MemProfile(p []MemProfileRecord, inuseZero bool) (n int, ok bool) MemProfile 返回当前内存profile中的记录数n 若len(p)nMemProfile会将此分析报告复制到p中并返回(n, true) 若len(p)nMemProfile则不会更改p而只返回(n, false) 如果inuseZero为true该profile就会包含无效分配记录其中r.AllocBytes0而r.AllocBytesr.FreeBytes。这些内存都是被申请后又释放回运行时环境的 大多数调用者应当使用runtime/pprof包或testing包的-test.memprofile标记而非直接调用MemProfile 14. Breakpoint() 执行一个断点 runtime.Breakpoint() 15. Stack() 获取程序调用go协程的栈踪迹历史 func Stack(buf []byte, all bool) int Stack 将调用其的go程的调用栈踪迹格式化后写入到buf中并返回写入的字节数 若all为true函数会在写入当前go程的踪迹信息后将其它所有go程的调用栈踪迹都格式化写入到buf中 package mainimport ( fmt runtime time)func main() { go showRecord() time.Sleep(time.Second) buf : make([]byte, 10000000000) runtime.Stack(buf, true) fmt.Println(string(buf))}func showRecord() { ticker : time.Tick(time.Second) for t : range ticker {  fmt.Println(t) }} 输出: 2023-04-19 17:25:26.386522 0800 CST m1.0011055432023-04-19 17:25:27.386892 0800 CST m2.0014893762023-04-19 17:25:28.386505 0800 CST m3.0011160432023-04-19 17:25:29.38553 0800 CST m4.0001543342023-04-19 17:25:30.385618 0800 CST m5.0002555842023-04-19 17:25:31.385817 0800 CST m6.0004683342023-04-19 17:25:32.385528 0800 CST m7.0001929182023-04-19 17:25:33.385646 0800 CST m8.000323543goroutine 1 [running]:main.main()        /Users/fliter/runtime-demo/15Stack.go:13 0x68goroutine 4 [chan receive]:main.showRecord()        /Users/fliter/runtime-demo/15Stack.go:19 0xaccreated by main.main        /Users/fliter/runtime-demo/15Stack.go:10 0x24 16. Caller() 获取当前函数或者上层函数的标识号、文件名、调用方法在当前文件中的行号 func Caller(skip int) (pc uintptr, file string, line int, ok bool) package mainimport ( fmt runtime)func main() { pc, file, line, ok : runtime.Caller(0) fmt.Println(pc)   // 4336410771 fmt.Println(file) // /Users/fliter/runtime-demo/16Caller.go fmt.Println(line) //9 fmt.Println(ok)   //true} pc 4336410771 不是main函数的标识,而是runtime.Caller 方法的标识,line 13 标识它在main方法中的第13行被调用 //package main////import (// fmt// runtime//)////func main() {// pc, file, line, ok : runtime.Caller(0)// fmt.Println(pc)   // 4336410771// fmt.Println(file) // /Users/fliter/runtime-demo/16Caller.go// fmt.Println(line) //9// fmt.Println(ok)   //true//}package mainimport ( fmt runtime)func main() { pc, _, line, _ : runtime.Caller(1) fmt.Printf(main函数的pc:%d\n, pc)      // main函数的pc:4364609931 fmt.Printf(main函数被调用的行数:%d\n, line) // main函数被调用的行数:250 show()}func show() { pc, _, line, _ : runtime.Caller(1) fmt.Printf(show函数的pc:%d\n, pc)      // show函数的pc:4364974271 fmt.Printf(show函数被调用的行数:%d\n, line) // show函数被调用的行数:27 // 这个是main函数的栈 pc, _, line, _  runtime.Caller(2) fmt.Printf(show的上层函数的pc:%d\n, pc)      // show的上层函数的pc:4364609931 fmt.Printf(show的上层函数被调用的行数:%d\n, line) // show的上层函数被调用的行数:250 pc, _, _, _  runtime.Caller(3) fmt.Println(pc) //4364778899 pc, _, _, _  runtime.Caller(4) fmt.Println(pc) // 0} golang获取调用者的方法名及所在行数[2] runtime.Caller的性能问题[3] 17. Callers() 获取与当前堆栈记录相关链的调用栈踪迹 func Callers(skip int, pc []uintptr) int 会把当前go程调用栈上的调用栈标识符填入切片pc中返回写入到pc中的项数。实参skip为开始在pc中记录之前所要跳过的栈帧数0表示Callers自身的调用栈1表示Callers所在的调用栈。返回写入p的项数 package mainimport ( fmt runtime)func main() { pcs : make([]uintptr, 10) i : runtime.Callers(1, pcs) fmt.Println(pcs[:i]) // [4311883569 4311525404 4311694372]} 获得了三个pc 其中有一个是main方法自身的 18. FuncForPC() 获取一个标识调用栈标识符pc对应的调用栈 func FuncForPC(pc uintptr) *Func package mainimport ( runtime)func main() { pcs : make([]uintptr, 10) i : runtime.Callers(1, pcs) for _, pc : range pcs[:i] {  println(runtime.FuncForPC(pc)) }} 输出: 0x102f660f00x102f5c9f00x102f64840 用途见下 19. Name() 获取调用栈所调用的函数的名字 func (f *Func) string package mainimport ( runtime)func main() { pcs : make([]uintptr, 10) i : runtime.Callers(1, pcs) for _, pc : range pcs[:i] {  funcPC : runtime.FuncForPC(pc)  println(funcPC.Name()) }} 输出: main.mainruntime.mainruntime.goexit 20. FileLine() 获取调用栈所调用的函数的所在的源文件名和行号 func (f *Func) FileLine(pc uintptr) (file string, line int) package mainimport ( runtime)func main() { pcs : make([]uintptr, 10) i : runtime.Callers(1, pcs) for _, pc : range pcs[:i] {  funcPC : runtime.FuncForPC(pc)  file, line : funcPC.FileLine(pc)  println(funcPC.Name(), file, line) }} 输出: main.main /Users/fliter/runtime-demo/20FileLine.go 9runtime.main /Users/fliter/.g/go/src/runtime/proc.go 259runtime.goexit /Users/fliter/.g/go/src/runtime/asm_arm64.s 1166 21. Entry() 获取该调用栈的调用栈标识符 func (f *Func) Entry() uintptr package mainimport ( runtime)func main() { pcs : make([]uintptr, 10) i : runtime.Callers(1, pcs) for _, pc : range pcs[:i] {  funcPC : runtime.FuncForPC(pc)  println(funcPC.Entry()) }} 输出: 431069912043105406724310690704 22. NumCgoCall() 获取当前进程执行的cgo调用次数 获取当前进程调用C方法的次数 func NumCgoCall() int64 package mainimport ( runtime)/*#include stdio.h*/import Cfunc main() { println(runtime.NumCgoCall()) // 1} 没有调用C的方法为什么是1呢因为 import C 会调用C包中的init方法 package mainimport ( runtime)/*   #include stdio.h   // 自定义一个c语言的方法   static void myPrint(const char* msg) {     printf(myPrint: %s, msg);   }*/import Cfunc main() { // 调用c方法 C.myPrint(C.CString(Hello,C\n)) // myPrint: Hello,C println(runtime.NumCgoCall()) // 3} 23. NumGoroutine() 获取当前存在的go协程数 func NumGoroutine() int package mainimport runtimefunc main() { go print() print() println(runtime.NumGoroutine()) // 2}func print() {} 当前程序有 2个go协程 一个是main.go主协程 另外一个是 go print() 24. Goexit() 终止掉当前的go协程 func Goexit() package mainimport ( fmt runtime)func main() { print() fmt.Println(继续执行)}func print() { fmt.Println(准备结束go协程) runtime.Goexit() defer fmt.Println(结束了)} 输出: 准备结束go协程fatal error: no goroutines (main called runtime.Goexit) - deadlock!exit status 2 Goexit终止调用它的go协程,其他协程不受影响,Goexit会在终止该go协程前执行所有的defer函数前提是defer必须在它前面定义如下 package mainimport ( fmt runtime)func main() { print() fmt.Println(继续执行)}func print() { fmt.Println(准备结束go协程) defer fmt.Println(结束了--会输出出来) runtime.Goexit() //defer fmt.Println(结束了)} 输出: 准备结束go协程结束了--会输出出来fatal error: no goroutines (main called runtime.Goexit) - deadlock!exit status 2 如果在 main主协程调用该方法,会终止 主协程,但不会让main返回,因为main函数没有返回, 程序会继续执行其他go协程,当其他go协程执行完毕后,程序就会崩溃 package mainimport ( fmt runtime time)func main() { start : time.Now() go func() {  time.Sleep(3e9)  println(123) }() defer fmt.Println(time.Since(start)) runtime.Goexit()} 输出: 20.5µs123fatal error: no goroutines (main called runtime.Goexit) - deadlock!exit status 2 25. Gosched() 让其他go协程优先执行,等其他协程执行完后,再执行当前的协程 func Gosched() package mainimport ( fmt)func main() { go print25() fmt.Println(继续执行)}func print25() { fmt.Println(执行打印方法)} 调用了go print方法,但是还未执行, main函数就执行完毕了启一个协程也是需要时间的这个时间比for循环比程序继续执行要耗时多很多 可以使用channelwaitgroup等此处使用 runtime.Gosched() package mainimport ( fmt runtime)func main() { go print25() runtime.Gosched() fmt.Println(继续执行)}func print25() { fmt.Println(执行打印方法)} 输出: 执行打印方法继续执行 Rust vs Go:常用语法对比(13)-将优先权让给其他线程[4] Go用两个协程交替打印100以内的奇偶数[5] 26. GoroutineProfile() 获取活跃的go协程的堆栈profile以及记录个数 func GoroutineProfile(p []StackRecord) (n int, ok bool) // GoroutineProfile returns n, the number of records in the active goroutine stack profile.// If len(p)  n, GoroutineProfile copies the profile into p and returns n, true.// If len(p)  n, GoroutineProfile does not change p and returns n, false.//// Most clients should use the runtime/pprof package instead// of calling GoroutineProfile directly.func GoroutineProfile(p []StackRecord) (n int, ok bool) { return goroutineProfileWithLabels(p, nil)} package mainimport ( fmt runtime)func main() { for i : 0; i  10; i {  go func(k int) {   fmt.Println(i)  }(i) } fmt.Println(----------------) p : make([]runtime.StackRecord, 10000) fmt.Println(runtime.GoroutineProfile(p)) // 1 true} 输出: 10101010101010----------------710101 true pprof里面使用了此func Go 应用的性能优化[6] 27. LockOSThread() 将调用的go协程绑定到当前所在的操作系统线程其它go协程不能进入该线程 func LockOSThread() 将调用的go程绑定到它当前所在的操作系统线程。除非调用的go程退出或调用UnlockOSThread否则它将总是在该线程中执行而其它go程不能进入该线程 package mainimport ( fmt runtime time)func main() { go calcSum1() go calcSum2() time.Sleep(time.Second * 10)}func calcSum1() { runtime.LockOSThread() start : time.Now() count : 0 for i : 0; i  10000000000; i {  count  i } end : time.Now() fmt.Println(calcSum1耗时) fmt.Println(end.Sub(start)) defer runtime.UnlockOSThread()}func calcSum2() { start : time.Now() count : 0 for i : 0; i  10000000000; i {  count  i } end : time.Now() fmt.Println(calcSum2耗时) fmt.Println(end.Sub(start))} 输出: calcSum1耗时3.295679583scalcSum2耗时3.296763125s 看起来没有太大的差别; 但估计在很多个协程(涉及到频繁的调度和切换)但是有一项重要功能需独占一个核可使用该func Go LockOSThread[7] 28. UnlockOSThread() 解除go协程与操作系统线程的绑定关系 func UnlockOSThread() 将调用此func的协程解除和其绑定的操作系统线程 若调用的协程未调用LockOSThreadUnlockOSThread不做操作 从1,10之后调用了多少次LockOSThread就要使用UnlockOSThread接触绑定.. 29. ThreadCreateProfile() 获取线程创建profile中的记录个数 func ThreadCreateProfile(p []StackRecord) (n int, ok bool) 返回线程创建profile中的记录个数。 如果len(p)n本func就会将profile中的记录复制到p中并返回(n, true) 若len(p)n则不会更改p而只返回(n, false) 绝大多数情况下应当使用runtime/pprof包而非直接调用ThreadCreateProfile 30. SetBlockProfileRate() 控制阻塞profile记录go协程阻塞事件的采样率 func SetBlockProfileRate(rate int) SetBlockProfileRate 控制阻塞profile记录go程阻塞事件的采样频率。对于一个阻塞事件平均每阻塞rate纳秒阻塞profile记录器就采集一份样本。 要在profile中包括每一个阻塞事件需传入rate1 要完全关闭阻塞profile的记录需传入rate0 31. BlockProfile() 返回当前阻塞profile中的记录个数 func BlockProfile(p []BlockProfileRecord) (n int, ok bool) BlockProfile返回当前阻塞profile中的记录个数 如果len(p)n本函数就会将此profile中的记录复制到p中并返回(n, true) 如果len(p)n本函数则不会修改p而只返回(n, false) 绝大多数情况应当使用runtime/pprof包或testing包的-test.blockprofile标记 而非直接调用 BlockProfile 参考资料 [1] 运行时 runtime的神奇用法: https://blog.csdn.net/u011525168/article/details/88401166 [2] golang获取调用者的方法名及所在行数: https://dashen.tech/2018/05/18/golang%E8%8E%B7%E5%8F%96%E8%B0%83%E7%94%A8%E8%80%85%E7%9A%84%E6%96%B9%E6%B3%95%E5%90%8D%E5%8F%8A%E6%89%80%E5%9C%A8%E8%A1%8C%E6%95%B0/ [3] runtime.Caller的性能问题: https://dashen.tech/2019/11/11/runtime-Caller%E7%9A%84%E6%80%A7%E8%83%BD%E9%97%AE%E9%A2%98/ [4] Rust vs Go:常用语法对比(13)-将优先权让给其他线程: https://json.dashen.tech/2021/09/14/Rust-vs-Go-%E5%B8%B8%E7%94%A8%E8%AF%AD%E6%B3%95%E5%AF%B9%E6%AF%94-13/ [5] Go用两个协程交替打印100以内的奇偶数: https://dashen.tech/2022/04/03/Go%E7%94%A8%E4%B8%A4%E4%B8%AA%E5%8D%8F%E7%A8%8B%E4%BA%A4%E6%9B%BF%E6%89%93%E5%8D%B0100%E4%BB%A5%E5%86%85%E7%9A%84%E5%A5%87%E5%81%B6%E6%95%B0/ [6] Go 应用的性能优化: https://zhuanlan.zhihu.com/p/406826295 [7] Go LockOSThread: https://dashen.tech/2017/07/11/Go-LockOSThread/ 本文由 mdnice 多平台发布
http://www.w-s-a.com/news/196828/

相关文章:

  • 北京公司网站网站建设html模板
  • 专门做医疗器械的网站免费网页制作系统团队
  • 网站开发技术 html临夏网站建设
  • flash网站模板免费下载拍卖网站开发多少钱
  • 北京网站建设制作颍州网站建设
  • 网站制作报价表做网站上海公司
  • 简洁大气蓝色文章资讯网站百度搜索广告推广
  • 河南建设工程协会网站网站收银系统建设
  • 网站制作 服务企业网站案例展示
  • 咸宁网站建设wordpress手动降级
  • 昆明做网站建设怎么样做网站赚钱全攻略
  • 企业网站建设实战教程微信如何注册小程序
  • 做一件代发网站百度seo服务
  • 小说网站开发 公司可以做行程的网站
  • 古交市网站建设公司apk连接wordpress
  • 网页 网 址网站区别wordpress菜单居右
  • 网站建设搭建运营一台云服务器做多个网站
  • 用php做网站用什么框架推广网站推荐
  • 如何用二级域名做网站多用户网上商城
  • 河南省建设科技网站浅谈电子商务网站建设与规划
  • 网站空间需要续费青海网站建设推广
  • 网站开发本地环境企业网站建设排名口碑
  • 做新闻的网站怎样赚钱个人网站课程设计报告
  • 网站设计样例那个网站做图片好看
  • 小型公司网站建设深圳网络营销策划有限公司
  • 国内优秀企业网站做视频网站用什么系统
  • 网站建设入门pdfwordpress网站标题
  • 专业网站的定义网站运营的概念
  • 外贸服装网站建设网页美工设计说明书
  • 郑州专业做网站公百度翻译api wordpress