golang:内存问题
golang : trouble with memory
我的记忆力有问题。我不明白为什么当我的程序运行很长时间时 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)
}))
//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
}
对于每次调用,我的服务需要使用我收到的参数生成一个新模板,如您所见,我为每次调用创建了一个新端点,我不知道这是否是个好主意,我认为问题来自这部分代码,但我不确定,因为我不知道 GO 是如何管理它的。
显然,您不应该在每次出现请求时都创建处理程序。他们从不释放内存,所以你最终会遇到内存不足的异常。
相反,将处理程序端点放入数组(切片)并使用一个处理程序通过查看此切片中的 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, ...})
它会起作用 because:
Patterns name fixed, rooted paths, like "/favicon.ico", or rooted subtrees, like "/images/" (note the trailing slash). Longer patterns take precedence over shorter ones, so that if there are handlers registered for both "/images/" and "/images/thumbnails/", the latter handler will be called for paths beginning "/images/thumbnails/" and the former will receive requests for any other paths in the "/images/" subtree.
当然不要忘记清理数组 jobs
。
与其使用 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, ...}
我的记忆力有问题。我不明白为什么当我的程序运行很长时间时 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)
}))
//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
}
对于每次调用,我的服务需要使用我收到的参数生成一个新模板,如您所见,我为每次调用创建了一个新端点,我不知道这是否是个好主意,我认为问题来自这部分代码,但我不确定,因为我不知道 GO 是如何管理它的。
显然,您不应该在每次出现请求时都创建处理程序。他们从不释放内存,所以你最终会遇到内存不足的异常。
相反,将处理程序端点放入数组(切片)并使用一个处理程序通过查看此切片中的 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, ...})
它会起作用 because:
Patterns name fixed, rooted paths, like "/favicon.ico", or rooted subtrees, like "/images/" (note the trailing slash). Longer patterns take precedence over shorter ones, so that if there are handlers registered for both "/images/" and "/images/thumbnails/", the latter handler will be called for paths beginning "/images/thumbnails/" and the former will receive requests for any other paths in the "/images/" subtree.
当然不要忘记清理数组 jobs
。
与其使用 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, ...}