Memory 葛朗:记忆有问题

Memory 葛朗:记忆有问题,memory,memory-management,go,endpoint,Memory,Memory Management,Go,Endpoint,我记忆力不好。我不明白为什么当我的程序运行很长时间时,Go会使用越来越多的内存(从未释放内存) 在第一次分配之后,程序使用了将近9MB的内存。12小时后,它开始以指数方式使用更多内存,直到800MB //.....code..... if bol { // Assignment Struct.Var Struct_VastScript.TxtNoticeTop = JsonStruct_S.Options.TxtNoticeTop Struct_VastScript.Tx

我记忆力不好。我不明白为什么当我的程序运行很长时间时,Go会使用越来越多的内存(从未释放内存)

在第一次分配之后,程序使用了将近9MB的内存。12小时后,它开始以指数方式使用更多内存,直到800MB

//.....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)
    }))


    //Call Func JsonReply(): return the finale Json response
    str := JsonReply(fpath, JsonStruct_S.Options.Animated, JsonStruct_S.Options.Responsive, JsonStruct_S.Options.Clickurl, JsonStruct_S.Options.Width, JsonStruct_S.Options.Height, adid, campaignid, JsonStruct_S.Type, JsonStruct_S.Options.Aspectratio, mobile)
    w.Header().Set("Content-Type", "application/json")
    //writes FinaleJson to 'w' http.ResponseWriter(it contains the link of the second endpoint "/api/html/")
    fmt.Fprint(w, str)
    fmt.Println("successfull Operation !!")
    fmt.Println("")
    job_1.Complete(health.Success)
    return true, nil
} else {
    return false, nil
}

对于每个调用,我的服务需要生成一个新模板,其中包含我收到的参数,正如您看到的,我为每个调用创建了一个新端点,我不知道这是否是一个好主意,我认为问题来自这部分代码,但我不确定,因为我不知道如何管理它。

显然,您不应该每次出现请求时都创建处理程序。它们永远不会释放内存,因此最终会出现内存不足异常

相反,将处理程序端点放入数组(slice)中,并使用一个处理程序来响应请求,方法是在该切片中查找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)
}))

它将在以下方面发挥作用:

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


当然,不要忘记清理数组
作业

不要使用切片最好使用映射

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, ...}

gracias说,它工作得非常好,代码清晰,但与其使用slice,不如使用map。
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, ...}