Go(lang)内存使用情况:RSIZE增长和VSIZE为139GB?

huangapple go评论91阅读模式
英文:

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

问题

我正在使用Go编写我的第一个Web服务器/ Web服务程序,我发现在重复向我的Web服务发送相同的请求后,RSIZE(如命令行程序“top”所示)会增长。这是否意味着存在内存泄漏?

我还注意到我的应用程序和“top”上的Go进程的VSIZE都为139GB(两者大小完全相同)。这正常吗?

我正在使用Go 1.1.2和OS X 10.8。

非常感谢。

英文:

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

答案1

得分: 4

大的VSIZE并不意味着你真的在使用物理内存;不用担心这个问题。

单个请求后RSIZE的增长也不令人担忧。内存会被垃圾回收机制回收,这会消耗CPU周期,因此Go和其他带有垃圾回收机制的语言会等待多个请求,直到需要释放内存(或者至少分配了大量内存)才会运行垃圾回收。较少的垃圾回收次数意味着CPU花费的时间更少。

通常意义上的内存泄漏是很少见的,因为垃圾回收机制应该会释放你没有引用的内存。如果你有根据需要增长但从不缩小的缓冲区,那么可能会产生类似泄漏的效果;如果你意外地持有对已经失效的内存的引用,可能会出现问题。但是,除非进程持续无限增长,否则我不会认为你在这里遇到了这个问题。

以下是一些Go语言的内存管理技巧;其中一些间接适用于其他语言:

  • 通常情况下,你不需要担心。垃圾回收通常很快,相对于数据的大小,你通常有很多可用的内存。在深入研究之前,请确保确实存在需要解决的问题。:)
  • runtime.ReadMemStats(ms) 可以告诉你程序在垃圾回收中花费了多长时间,以及其他很多有用的信息,比如你分配了多少内存(请参阅 runtime 模块文档:http://golang.org/pkg/runtime/)
  • 如果你在垃圾回收中花费的时间过多,并且不知道原因,可以使用 memprofile 进行下一步分析;Go博客上有一个完整的示例,涉及给程序添加一个可选的 -memprofile 标志:http://blog.golang.org/profiling-go-programs
  • 一般来说,通过减少不必要的分配来减少垃圾回收次数,特别是大对象的分配(比如保存整个HTTP响应的缓冲区)。
    • 有时候可以在不复杂化程序的情况下自然地做到这一点,比如可以将输出流式传输到 Writer 而不是缓冲一个大的响应,或者在循环的多次迭代中重用一个对象而不是每次都分配。
    • 其他时候,你可以对大型/经常分配的对象进行_回收利用_,而不是创建新的对象;标准的 sync.Pool 包可以帮助实现这一点,CloudFlare博客上有一个关于回收利用的很好的通用描述(在 sync.Pool 成为标准之前):http://blog.cloudflare.com/recycling-memory-buffers-in-go
英文:

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. Go(lang)内存使用情况:RSIZE增长和VSIZE为139GB?
  • 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.

huangapple
  • 本文由 发表于 2013年9月30日 00:50:02
  • 转载请务必保留本文链接:https://go.coder-hub.com/19080637.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定