• golang 栈、堆分配分析及CPU、内存性能情况


    一、逃逸分析

    堆:一般来讲是人为手动进行管理,手动申请、分配、释放。一般所涉及的内存大小并不定,一般会存放较大的对象。另外其分配相对慢,涉及到的指令动作也相对多

    栈:由编译器进行管理,自动申请、分配、释放。一般不会太大,我们常见的函数参数(不同平台允许存放的数量不同),局部变量等等都会存放在栈上

    反编译为汇编代码:go tool compile -S main.go

    栈、堆逃逸分析:go build -gcflags '-m -l' main.go

    二、CPU、内存性能情况

    1、time go run main.go

       real 0m0.843s   //从程序开始到结束,实际度过的时间;

       user 0m0.216s  //程序在用户态度过的时间;

       sys 0m0.389s  //程序在内核态度过的时间

    2、/usr/bin/time -v go run test2.go

    3、调用 runtime中的 ReadMemStats()方法获得内存信息,然后通过 log打印出来。

    package main
    
    import (
    "log"
    "runtime"
    "time"
    )
    
    func readMemStats() {
    
    var ms runtime.MemStats
    
        runtime.ReadMemStats(&ms)
    
        log.Printf(" ===> Alloc:%d(bytes) HeapIdle:%d(bytes) HeapReleased:%d(bytes)", ms.Alloc, ms.HeapIdle, ms.HeapReleased)
    }
    
    func test() {
    //slice 会动态扩容,用slice来做堆内存申请
        container := make([]int, 8)
    
        log.Println(" ===> loop begin.")
    for i := 0; i < 32*1000*1000; i++ {
            container = append(container, i)
    if ( i == 16*1000*1000) {
                readMemStats()
            }
        }
    
        log.Println(" ===> loop end.")
    }
    
    func main() {
        log.Println(" ===> [Start].")
    
        readMemStats()
        test()
        readMemStats()
    
        log.Println(" ===> [force gc].")
        runtime.GC() //强制调用gc回收
    
        log.Println(" ===> [Done].")
        readMemStats()
    
        go func() {
        for {
                readMemStats()
                time.Sleep(10 * time.Second)
            }
        }()
    
        time.Sleep(3600 * time.Second) //睡眠,保持程序不退出
    }

    4、pprof网页监控

    package main
    
    import (
    "log"
    "runtime"
    "time"
    "net/http"
        _ "net/http/pprof"
    )
    
    func readMemStats() {
    
    var ms runtime.MemStats
    
        runtime.ReadMemStats(&ms)
    
        log.Printf(" ===> Alloc:%d(bytes) HeapIdle:%d(bytes) HeapReleased:%d(bytes)", ms.Alloc, ms.HeapIdle, ms.HeapReleased)
    }
    
    func test() {
    //slice 会动态扩容,用slice来做堆内存申请
        container := make([]int, 8)
    
        log.Println(" ===> loop begin.")
    for i := 0; i < 32*1000*1000; i++ {
            container = append(container, i)
    if ( i == 16*1000*1000) {
                readMemStats()
            }
        }
    
        log.Println(" ===> loop end.")
    }
    
    func main() {
    
    
    //启动pprof
    go func() {
            log.Println(http.ListenAndServe("0.0.0.0:10000", nil))
        }()
    
        log.Println(" ===> [Start].")
    
        readMemStats()
        test()
        readMemStats()
    
        log.Println(" ===> [force gc].")
        runtime.GC() //强制调用gc回收
    
        log.Println(" ===> [Done].")
        readMemStats()
    
    go func() {
    for {
                readMemStats()
                time.Sleep(10 * time.Second)
            }
        }()
    
        time.Sleep(3600 * time.Second) //睡眠,保持程序不退出
    }

    记录了目前的内存情况:http://127.0.0.1:10000/debug/pprof/heap?debug=1

    记录了目前的CPU情况:http://127.0.0.1:10000/debug/pprof/

    5、gin使用pprof

    5.1 安装:go get https://github.com/gin-contrib/pprof

    5.2 在main.go写入监控: 

    package main
    
    import (
        "github.com/gin-contrib/pprof"
        "github.com/gin-gonic/gin"
    )
    
    func main() {
        s := gin.Default()
    
        // 方式一:性能
        pprof.Register(s)
    
        // 方式二:性能 - 授权访问
        a := s.Group("/admin", gin.BasicAuth(gin.Accounts{"root": "888000"}))
        pprof.RouteRegister(a)
    
        s.Run(":8080")
    }

    5.3 web访问:http://127.0.01:8080/admin/debug/pprof/

    5.4 页面参数:

    类型描述备注
    allocs 内存分配情况的采样信息 可以用浏览器打开, 但可读性不高
    blocks 阻塞操作情况的采样信息 可以用浏览器打开, 但可读性不高
    cmdline 显示程序启动命令及参数 可以用浏览器打开
    goroutine 当前所有协程的堆栈信息 可以用浏览器打开, 但可读性不高
    heap 堆上内存使用情况的采样信息 可以用浏览器打开, 但可读性不高
    mutex 锁争用情况的采样信息 可以用浏览器打开, 但可读性不高
    profile CPU 占用情况的采样信息, 持续 30s 浏览器打开会下载文件
    threadcreate 系统线程创建情况的采样信息 可以用浏览器打开, 但可读性不高
    trace 程序运行跟踪信息 浏览器打开会下载文件

    5.5 终端交互命令:

    • go tool pprof http://localhost:8080/debug/pprof/profile?seconds=60

    输入 top10

    说明
    flat 给定函数上运行耗时
    flat% 同上的 CPU 运行耗时总比例
    sum% 给定函数累积使用 CPU 总比例
    cum 当前函数加上它之上的调用运行总耗时
    cum% 同上的 CPU 运行耗时总比例
    • go tool pprof http://localhost:8080/debug/pprof/heap

    type 类型

    说明
    inuse_space 分析应用程序的常驻内存占用情况
    alloc_objects 分析应用程序的内存临时分配情况
    • go tool pprof http://localhost:8080/debug/pprof/block

    • go tool pprof http://localhost:8080/debug/pprof/mutex

    5.6 可视化界面

    启动方式一:go tool pprof -http=:8080 cpu.prof

    启动方式二:go tool pprof cpu.prof

  • 相关阅读:
    oracle启动的三步
    Solaris下vi的简单使用帮助
    Solaris下ftp配置(初稿待补充)
    soap笔记1
    Solaris 10 查看机器的网卡mac地址
    查看表空间名称与对应文件
    [转]Ubuntu10.04的网络配置
    [转]红帽企业版RHEL6使用Fedora13的yum源
    [转]linux忘记密码怎么办法
    [转]个人管理 - IT人士书籍推荐(已读)
  • 原文地址:https://www.cnblogs.com/wu-wu/p/14585375.html
Copyright © 2020-2023  润新知