为了账号安全,请及时绑定邮箱和手机立即绑定

golang:内存问题

golang:内存问题

Go
有只小跳蛙 2021-10-25 18:22:36
我记忆力有问题。我不明白为什么当我的程序运行很长时间时 Go 使用越来越多的内存(从不释放它)。第一次分配后,程序使用了近 9 MB 的内存。然后 12 小时后它开始以指数方式使用更多内存,直到 800 MB。//.....code.....if bol {    // Assignment Struct.Var    Struct_VastScript.TxtNoticeTop = JsonStruct_S.Options.TxtNoticeTop    Struct_VastScript.TxtNoticeBottom = JsonStruct_S.Options.TxtNoticeBottom    Struct_VastScript.Loop = JsonStruct_S.Options.Loop    Struct_Image, err := getImage(Struct_VastScript.Video)    if err == nil {        if mobile == "true" {            Struct_VastScript.Image = Struct_Image.URL360        }    }    //open and parse a template file    fi = path.Join("templates/VastPlayer", "TempVastPlayer.txt")    tmpl, err := template.ParseFiles(fi)    if err != nil {        job_1.Complete(health.Panic)        return false, err    }    //substitute fields in the template 'tmpl', with values from 'XmlStruct_V' and write it out to 'buf'    var buf bytes.Buffer    if err := tmpl.Execute(&buf, Struct_VastScript); err != nil {        //if  err := tmpl.Execute(w, XmlStruct_V); err != nil {        job_1.Complete(health.Panic)        return false, err    }    // Call Func randString() : return alphanum random    dir := randString(12)    fpath := "http://creative2.xxx.io/api/html/" + dir    // Create a new EndPoint to write the generated 'template' on 'w' http.ResponseWriter    routeHtml := "/api/html/" + dir    http.HandleFunc(routeHtml, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {        //writes Template to 'w' http.ResponseWriter        fmt.Fprintf(w, buf.String())        fmt.Println("successfull Operation 2 !!")        fmt.Println("")        job_2.Complete(health.Success)    }))对于每次调用,我的服务需要使用我收到的参数生成一个新模板,如您所见,我为每个调用创建了一个新端点,我不知道这是否是个好主意,我认为问题出在这部分代码,但我不确定,因为我不知道 GO 如何管理它。
查看完整描述

2 回答

?
慕尼黑的夜晚无繁华

TA贡献1864条经验 获得超6个赞

显然,您不应该每次出现请求时都创建处理程序。他们从不释放内存,所以你最终会遇到内存不足的异常。


相反,将处理程序端点放入数组(切片)并使用 ONE 处理程序,该处理程序通过查看此切片中的 URL 来响应请求,然后从切片中删除不再需要的项目。


所以基本上,而不是


routeHtml := "/api/html/" + dir

http.HandleFunc(routeHtml, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {

    //writes Template to 'w' http.ResponseWriter

    fmt.Fprintf(w, buf.String())

    fmt.Println("successfull Operation 2 !!")

    fmt.Println("")

    job_2.Complete(health.Success)

}))


type JobInfo struct {

    Path string

    // some data here

}


// maybe global context

var jobs []JobInfo


// initialisation

jobs = make([]JobInfo, 0)


http.HandleFunc("/api/html/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {

    path := r.URL.Path

    var job *JobInfo

    for _, j := range jobs {

        if j.Path == path {

            job = &j

            break

        }

    }


    if job != nil {

        // handle job request here

    }

}))


// and then in the jobs' loop

handlers = append(handlers, JobInfo{"/api/html/" + dir, ...})

它会起作用,因为:


模式命名固定的根路径,如“/favicon.ico”,或根子树,如“/images/”(注意尾部斜杠)。较长的模式优先于较短的模式,因此如果“/images/”和“/images/thumbnails/”都注册了处理程序,则将为以“/images/thumbnails/”和前者开头的路径调用后一个处理程序将接收对“/images/”子树中任何其他路径的请求。


jobs当然,不要忘记清理数组。


查看完整回答
反对 回复 2021-10-25
?
慕码人2483693

TA贡献1860条经验 获得超9个赞

而不是使用切片最好使用地图


type JobInfo struct {

    Path string

    // some data here

}


    // global context

    var jobs map[string]JobInfo


// initialisation

jobs = make(map[string]JobInfoStruct)



http.HandleFunc("/api/html/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {

    path := r.URL.Path

    var job JobInfoStruct

    var ok bool


    job, ok = jobs[path]

    if ok {

      // handle job request here

      //then after delete the job

      delete(jobs, path)

    }


}))


 // and then in the jobs' loop

pathVideo := "/api/html/" + dir

jobs[pathVideo] = JobInfoStruct{pathVideo, ...}


查看完整回答
反对 回复 2021-10-25
  • 2 回答
  • 0 关注
  • 254 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信