Test Memory on go

peta · · 2319 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。


package main

import (
    "container/list"
    "fmt"
    "net/http"
    "os"
    "runtime"
    "strconv"
    // "strings"
    "io"
    "log"
    "sync"
    "syscall"
    "time"
)

var lockger sync.Mutex
var fansMap map[int]*list.List

func root(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "<h1>Hello %s!</h1>", r.URL.Path[1:])
    url := "get?key=123"
    fmt.Fprintf(w, "<a href=%s>%s</a><br />", url, url)
    url = "set?key=123&v=100"
    fmt.Fprintf(w, "<a href=%s>%s</a><br />", url, url)
    url = "stop"
    fmt.Fprintf(w, "<a href=%s>%s</a><br />", url, url)
}
func setData(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "...")
    runtime.GC()
}
func getData(w http.ResponseWriter, r *http.Request) {
    key := r.FormValue("key")
    i, _ := strconv.Atoi(key)
    fmt.Fprintf(w, "val:%d", i)
    lockger.Lock()
    l, ok := fansMap[i]
    lockger.Unlock()
    if ok {
        fmt.Fprintf(w, "mapok\n")
        for e := l.Front(); e != nil; e = e.Next() {
            // do something with l.Value
            v := e.Value.(int)
            fmt.Fprintf(w, "%d,", v)
        }
    }
    //r.ParseForm()
    //for k, v := range r.Form {
    //    fmt.Fprintf(w, "key:%s", k)
    //    fmt.Fprintf(w, "val:%d", v)
    //    //i, _ := strconv.Atoi(v)
    //}
}

// getEnv Request Handler
func getEnv(writer http.ResponseWriter, req *http.Request) {
    env := os.Environ()
    writer.Write([]byte("<h1>??????</h1><br>"))
    for _, v := range env {
        writer.Write([]byte(v + "<br>"))
    }
    writer.Write([]byte("<br>"))
}
func StopServer(w http.ResponseWriter, req *http.Request) {
    responseString := "STOP"
    w.Header().Set("Content-Type", "text/plain; charset=utf-8")
    w.Header().Set("Content-Length", strconv.Itoa(len(responseString)))
    io.WriteString(w, responseString)
    f, canFlush := w.(http.Flusher)
    if canFlush {
        f.Flush()
    }
    conn, _, err := w.(http.Hijacker).Hijack()
    if err != nil {
        log.Fatalf("error while shutting down: %v", err)
    }
    conn.Close()
    log.Println("Shutting down")
    os.Exit(0)
}
func main() {
    np := runtime.NumCPU()
    runtime.GOMAXPROCS(np - 1)
    println(np)

    go ReportStatus()
    fansMap = make(map[int]*list.List)
    t := time.Now()
    var i int
    var fans *list.List
    max := 1000000
    for i = 0; i < max; i++ {
        fans = list.New()
        fansMap[i] = fans
        for j := 1; j <= 200; j++ {
            _ = fans.PushFront(j)
        }
        fans.PushFront(i)

        if i%1000 == 0 {
            fmt.Println("i=", i)
        }

        memstatus := MemStat()
        if memstatus.Free < 512000000 {
            fmt.Println("OUT OF MEMORY")
            break
        }
    }

    fmt.Println("list: " + time.Now().Sub(t).String())
    http.HandleFunc("/", root)
    http.HandleFunc("/get", getData)
    http.HandleFunc("/set", setData)
    http.HandleFunc("/stop", StopServer)
    http.HandleFunc("/env", getEnv)
    http.ListenAndServe(":8080", nil)
}

type MemStatus struct {
    All  uint32 `json:"all"`
    Used uint32 `json:"used"`
    Free uint32 `json:"free"`
    Self uint64 `json:"self"`
}

func MemStat() MemStatus {
    //自身占用
    memStat := new(runtime.MemStats)
    runtime.ReadMemStats(memStat)
    mem := MemStatus{}
    mem.Self = memStat.Alloc

    //系统占用,仅linux/mac下有效
    //system memory usage
    sysInfo := new(syscall.Sysinfo_t)
    err := syscall.Sysinfo(sysInfo)
    if err == nil {
        mem.All = sysInfo.Totalram * uint32(syscall.Getpagesize())
        mem.Free = sysInfo.Freeram * uint32(syscall.Getpagesize())
        mem.Used = mem.All - mem.Free
    }
    return mem
}
func ReportStatus() {
    memStats := &runtime.MemStats{}
    runtime.ReadMemStats(memStats)
    nsInMs := float64(time.Millisecond)
    prefix := "MT"
    for {
        //now := time.Now()
        fmt.Println("=========")

        fmt.Println(fmt.Sprintf("%s.goroutines", prefix),
            float64(runtime.NumGoroutine()))
        fmt.Println(fmt.Sprintf("%s.memory.allocated", prefix),
            float64(memStats.Alloc))
        fmt.Println(fmt.Sprintf("%s.memory.mallocs", prefix),
            float64(memStats.Mallocs))
        fmt.Println(fmt.Sprintf("%s.memory.frees", prefix),
            float64(memStats.Frees))
        fmt.Println(fmt.Sprintf("%s.memory.gc.total_pause", prefix),
            float64(memStats.PauseTotalNs)/nsInMs)
        fmt.Println(fmt.Sprintf("%s.memory.heap", prefix),
            float64(memStats.HeapAlloc))
        fmt.Println(fmt.Sprintf("%s.memory.stack", prefix),
            float64(memStats.StackInuse))
        time.Sleep(10e8)
    }

}

//func   reportRuntimeStats(prefix, context string,
//  dimensions Dimensions, sleep time.Duration) {

//  memStats := &runtime.MemStats{}
//  lastSampleTime := time.Now()
//  var lastPauseNs uint64 = 0
//  var lastNumGc uint32 = 0

//  nsInMs := float64(time.Millisecond)

//  for self.runtimeStatsRunning {
//    runtime.ReadMemStats(memStats)

//    now := time.Now()

//    Println(fmt.Sprintf("%s.goroutines", prefix),
//      float64(runtime.NumGoroutine()), now, context, dimensions)
//    Println(fmt.Sprintf("%s.memory.allocated", prefix),
//      float64(memStats.Alloc), now, context, dimensions)
//    Println(fmt.Sprintf("%s.memory.mallocs", prefix),
//      float64(memStats.Mallocs), now, context, dimensions)
//    Println(fmt.Sprintf("%s.memory.frees", prefix),
//      float64(memStats.Frees), now, context, dimensions)
//    Println(fmt.Sprintf("%s.memory.gc.total_pause", prefix),
//      float64(memStats.PauseTotalNs)/nsInMs, now, context, dimensions)
//    Println(fmt.Sprintf("%s.memory.heap", prefix),
//      float64(memStats.HeapAlloc), now, context, dimensions)
//    Println(fmt.Sprintf("%s.memory.stack", prefix),
//      float64(memStats.StackInuse), now, context, dimensions)

//    if lastPauseNs > 0 {
//      pauseSinceLastSample := memStats.PauseTotalNs - lastPauseNs
//      Println(fmt.Sprintf("%s.memory.gc.pause_per_second", prefix),
//        float64(pauseSinceLastSample)/nsInMs/sleep.Seconds(), now, context, dimensions)
//    }
//    lastPauseNs = memStats.PauseTotalNs

//    countGc := int(memStats.NumGC - lastNumGc)
//    if lastNumGc > 0 {
//      diff := float64(countGc)
//      diffTime := now.Sub(lastSampleTime).Seconds()
//      Println(fmt.Sprintf("%s.memory.gc.gc_per_second", prefix),
//        diff/diffTime, now, context, dimensions)
//    }

//    // get the individual pause times
//    if countGc > 0 {
//      if countGc > 256 {
//        fmt.Fprintf(os.Stderr, "We're missing some gc pause times")
//        countGc = 256
//      }

//      for i := 0; i < countGc; i++ {
//        idx := int((memStats.NumGC-uint32(i))+255) % 256
//        pause := float64(memStats.PauseNs[idx])
//        self.Aggregate(fmt.Sprintf("%s.memory.gc.pause", prefix),
//          pause/nsInMs, context, dimensions)
//      }
//    }

//    // keep track of the previous state
//    lastNumGc = memStats.NumGC
//    lastSampleTime = now

//    time.Sleep(sleep)
//  }
//}



有疑问加站长微信联系(非本文作者)

本文来自:CSDN博客

感谢作者:peta

查看原文:Test Memory on go

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

2319 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传