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)
// }
//}
有疑问加站长微信联系(非本文作者)