Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Go(lang) memory usage: RSIZE growing and VSIZE of 139GB?

I am writing my first webserver/webservices program in Go and I realized that the RSIZE (as shown by the command line program "top") grows after repeating the same request to my webservices. Does that means there is a memory leak?

I also noticed that both my app and the go process on "top" have a VSIZE of 139GB (both of them exactly that size). Is it normal?

I am using Go 1.1.2 on OS X 10.8

Many Thanks

like image 690
Daniele B Avatar asked Sep 29 '13 16:09

Daniele B


People also ask

Does Golang have memory leak?

Memory leaks are very common in almost any language, including garbage collected languages. Go is not an exception. A reference to an object, if not properly managed, may be left assigned even if unused.

How much memory does a Golang map use?

This is detailed in this answer: How to get variable memory size of variable in golang? So the answer is on my 64-bit architecture: 48 bytes. A map of type map[string]int with an initial capacity of 100 now requires 4176 bytes (on 64-bit arch). The default initial capacity is around 7 if not specified explicitly.

How is Golang memory efficient?

Only the values stored in the memory managed by the stack are changed. This makes the process of storing and retrieving data from the stack very fast since there is no lookup required. We can just store and retrieve data from the top most block on it. Any data that is stored on the stack has to be finite and static.

How do I find a memory leak in go?

pprof and flame graphs are pretty useful to analyze application memory leaks. A continuous profiler can really help you look at multiple snapshots of the profile and quickly figure out the cause of leaks. Cloud profiler is definitely a handy tool for GCP workloads.


1 Answers

Big VSIZE doesn't mean you're really using physical memory; wouldn't worry about that.

RSIZE growing after a single request also isn't worrying. RAM's reclaimed by garbage collection, which costs CPU cycles, so Go and other GC'd languages wait many requests until they need RAM freed up (or at least until a lot of RAM has been allocated) to run a collection. Fewer collections => less CPU time spent.

Leaks in the usual sense are rare because the GC should eventually free memory you aren't holding a reference to. If you have buffers that grow as needed but never shrink, those can have a leak-like effect, and if you accidentally hold a reference to memory that's really dead you can have problems. But unless the process keeps growing forever, I wouldn't assume you're having that problem here.

Here are some memory-management tips for Go; some indirectly apply to other languages, too:

  • You often don't need to worry. Collection is often pretty fast and you often have a lot of RAM to play with relative to the size of your data. Before you dive in, be sure there's a problem there to solve. :)
  • runtime.ReadMemStats(ms) can tell you how long your program has spent in GC, along with lots of other useful information like how much you're allocating (see runtime module docs at http://golang.org/pkg/runtime/)
  • If you're spending too much time in GC and don't know why, memprofile is the next step; a full example involving giving a program an optional -memprofile flag is on the Go blog: http://blog.golang.org/profiling-go-programs
  • In general, you reduce GC's by reducing unneeded allocations, especially allocations of big objects (buffers holding whole HTTP responses, say).
    • Sometimes there are natural ways to do that without complicating your program--you can stream output to a Writer instead of buffering up a big response, or reuse an object across several iterations of a loop instead of allocating each time, for instance.
    • Other times, you can recycle large/often-allocated objects instead of making new ones; the standard sync.Pool package helps with that, and there's a nice general description of recycling (from before sync.Pool was standard) on the CloudFlare blog.
like image 136
twotwotwo Avatar answered Dec 18 '22 11:12

twotwotwo