Pugo one time memory leak tuning

Source: Internet
Author: User
This is a creation in Article, where the information may have evolved or changed.

I just wrote a new blog program Pugo, Welcome to try and experience. These two days I moved a station fuxiaohei.me to a new blogging program. However, after a day of operation, it was found that the memory from the boot 14MB rose to 228 MB. Obviously the program has a memory leak, so the following tuning process is also started.

PPROF

Pprof is a debug tool that comes with Golang, and there are many tools available. Pprof debugging methods have code and HTTP mode. Where HTTP debugging is more convenient, add a very simple code:

import _ "net/http/pprof" // pprof 的 http 路由注册在自带路由上go func() {    http.ListenAndServe("0.0.0.0:6060", nil) // 启动默认的 http 服务,可以使用自带的路由}()

Access http://localhost:6060/debug/pprof/ to view the information provided by PPROF. Analyzing memory usage, you can focus on what variables are allocated on the heap, and access http://localhost:6060/debug/pprof/heap?debug=1 the data you can see:

github.com/syndtr/goleveldb/leveldb/memdb.Newthe object from the code is the largest on the heap. The database underlying the Pugo is a TIDB database based on GOLEVELDB storage. GOLEVELDB has a behavior similar to LEVELDB, which is a half-memory half-stored data distribution. Therefore, there are a lot of memory objects are normal phenomenon. But there are other problems when using the Go tool:

go tool pprof http://localhost:6060/debug/pprof/heap

The Go tool temporarily saves the current heap snapshot for analysis. At the same time entered the Pprof tool, with the command:

top -10

Show the 10 most occupied object heaps

reflect.Value.callis the most call on the heap, hehe. The problem falls on the standard library, which may be the problem with the Golang standard library. I am still on the Go 1.5 version. After trying to update the Go 1.5.1, we found that the data distribution on the heap didn't change. That's not the problem with the standard library.

In-depth analysis

Since it is not a problem with the standard library, reflect.Value.call there is a problem with the call's superiors. To generate an SVG process diagram to a browser with a command:

web

The obvious problematic part of a time series diagram:

Found tango.(*Context).Next to be the supervisor of the Dispatch. However, the Next () method does not have a reflect calling process in the source code, not clear enough. Auxiliary with another command:

peek reflect.Value.Call

There are graphs:

You can see the context method tango.(*Context).Invoke , which is found in the code:

if ctx.action != nil {    var ret []reflect.Value    switch fn := ctx.route.raw.(type) {    case func(*Context):        fn(ctx)    case func(*http.Request, http.ResponseWriter):        fn(ctx.req, ctx.ResponseWriter)    case func():        fn()    case func(*http.Request):        fn(ctx.req)    case func(http.ResponseWriter):        fn(ctx.ResponseWriter)    default:        ret = ctx.route.method.Call(ctx.callArgs) // 调用 reflect.Value.Call 的地方    }    if len(ret) == 1 {        ctx.Result = ret[0].Interface()    } else if len(ret) == 2 {        if code, ok := ret[0].Interface().(int); ok {            ctx.Result = &StatusResult{code, ret[1].Interface()}        }    }    // not route matched} else {    if !ctx.Written() {        ctx.NotFound()    }}

After giving this position back to Tango's author Lunny, the final positioning problem in the router pool is constructed by:

func newPool(size int, tp reflect.Type) *pool {    return &pool{        size: size,        cur:  0,        pool: reflect.MakeSlice(reflect.SliceOf(tp), size, size), // 这个地方申请了大内存        tp:   reflect.SliceOf(tp),        stp:  tp,    }}

reflect.MakeSliceThe size default value is 800, which is to create a pool with a length of 800 slice, and the memory keeps growing. Then there's the reflect in the pool. Value is always called, so the heap can see the dispatch information. Modify the size default value to about 10, everything is fine.

Summarize

The profile tool provided by Golang itself is good enough to provide a lot of information. Then I go through the analysis and tracking of the code to find out where the problem lies. Debugging and optimization is something that you often encounter in your work. Each analysis process has accumulated the way of thinking and the experience of revising.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.