golang - mem 使用量
./memLimit 0.35 (限制使用率35%,使用0.35 作为参数)
- memLimit
`
package main
import (
"fmt"
"io"
"io/ioutil"
"log"
"math"
"os"
"os/exec"
"runtime"
"runtime/debug"
"strconv"
"strings"
// "syscall"
"time"
)
func main() {
// limitPer := 0.9
limitPer, _ := strconv.ParseFloat(os.Args[1], 64)
if limitPer <= 0 {
os.Exit(1)
}
_, total := getMEMSample()
var chArr []chan bool = make([]chan bool, int(math.Floor(float64(total)/512)))
var fileNameArr []string = make([]string, int(math.Floor(float64(total)/512)))
for i := 0; i < int(math.Floor(float64(total)/512)); i++ {
chArr[i] = make(chan bool)
fileNameArr[i] = "fileName"
}
err := os.Mkdir("./memCmd", 0755)
if err != nil {
fmt.Println("create memCmd file error")
}
defer killAllFile(fileNameArr)
tag := 0
for {
free, total := getMEMSample()
memUsage, _ := strconv.ParseFloat(fmt.Sprintf("%.3f", float64(total-free)/float64(total)), 64)
//fmt.Println(free/1024, total/1024)
fmt.Println("memUsage: ", memUsage)
if tag > 0 && memUsage > limitPer {
//fmt.Println("tag---: ", tag)
chArr[tag-1] <- true
fileNameArr[tag-1] = "fileName"
tag -= 1
} else if memUsage < limitPer {
//fmt.Println("tag++++: ", tag)
newFileName := "./memCmd/" + strconv.FormatInt(time.Now().Unix(), 10)
CopyFile("./mem-base", newFileName)
fileNameArr[tag] = newFileName
go RunSomething(chArr[tag], newFileName)
tag += 1
}
time.Sleep(time.Duration(10) * time.Second)
fmt.Println("now thread: ", tag)
runtime.GC()
debug.FreeOSMemory()
}
}
func RunSomething(endTag chan bool, cmdFileName string) {
cmd := exec.Command(cmdFileName)
// fmt.Println("cmdFileName: ", cmdFileName)
// defer cmd.Process.Kill()
err := cmd.Start()
fmt.Println("PID: ", cmd.Process.Pid)
if err != nil {
fmt.Println(err)
}
for {
select {
case ag := <-endTag:
fmt.Println(ag)
goto end
default:
time.Sleep(time.Duration(1) * time.Second)
}
}
end:
cmd.Process.Kill()
cmd.Wait()
// cmd.Process.Signal(syscall.SIGINT)
err = os.Remove(cmdFileName)
if err != nil {
fmt.Println("删除", cmdFileName, "失败: ", err)
}
}
func killAllFile(fileNameArr []string) {
for _, v := range fileNameArr {
fmt.Println("fileName: ", v)
if v != "fileName" {
os.Remove(v)
}
time.Sleep(time.Duration(1) * time.Second)
}
}
func getMEMSample() (free, total uint64) {
contents, err := ioutil.ReadFile("/proc/meminfo")
if err != nil {
return
}
lines := strings.Split(string(contents), "\n")
for _, line := range lines {
fields := strings.Fields(line)
if len(fields) > 0 && fields[0] == "MemFree:" {
free, err = strconv.ParseUint(fields[1], 10, 64)
if err != nil {
fmt.Println("Error: ", 1, fields[1], err)
}
} else if len(fields) > 0 && fields[0] == "MemTotal:" {
total, err = strconv.ParseUint(fields[1], 10, 64)
if err != nil {
fmt.Println("Error: ", 1, fields[1], err)
}
}
}
return
}
func CopyFile(srcFileName string, dstFileName string) {
//打开源文件
srcFile, err := os.Open(srcFileName)
if err != nil {
log.Fatalf("源文件读取失败,原因是:%v\n", err)
}
defer func() {
err = srcFile.Close()
if err != nil {
log.Fatalf("源文件关闭失败,原因是:%v\n", err)
}
}()
//创建目标文件,稍后会向这个目标文件写入拷贝内容
distFile, err := os.Create(dstFileName)
os.Chmod(distFile.Name(), 0755)
if err != nil {
log.Fatalf("目标文件创建失败,原因是:%v\n", err)
}
defer func() {
err = distFile.Close()
if err != nil {
log.Fatalf("目标文件关闭失败,原因是:%v\n", err)
}
}()
//定义指定长度的字节切片,每次最多读取指定长度
var tmp = make([]byte, 1024*4)
//循环读取并写入
for {
n, err := srcFile.Read(tmp)
n, _ = distFile.Write(tmp[:n])
if err != nil {
if err == io.EOF { //读到了文件末尾,并且写入完毕,任务完成返回(关闭文件的操作由defer来完成)
return
} else {
log.Fatalf("拷贝过程中发生错误,错误原因为:%v\n", err)
}
}
}
}
`
- mem-base
`
package main
import (
"math/rand"
"time"
)
func main() {
tmpChan := make(chan int, 50010241024)
defer close(tmpChan)
for i := 0; i < 50010241024-10; i++ {
tmpChan <- rand.Intn(10)
}
for {
time.Sleep(time.Duration(1) * time.Second)
}
}
`