Tracking down references/roots for memory

163 views
Skip to first unread message

Levi Corcoran

unread,
Aug 6, 2015, 1:29:55 AM8/6/15
to golang-nuts
Using pprof to troubleshoot memory leaks, we've isolated some types that are surviving GC much longer than expected.  The tooling is great for identifying the source of allocations, but I'm having a hard time figuring out why these are still referenced/rooted and are not being GC'd.  I've implemented a mechanism to capture heap dumps via runtime/debug.WriteHeapDump(), and since we're on Go 1.4.2 I've tried using heapdump14 to analyze the dump, but sadly that's failing due to some cgo usage (issue here).

Are there any other tools for analyzing 1.4 heap dumps, or other strategies for identifying what is still referencing types we wouldn't expect to stick around after a GC?  We're investigating the feasibility of eliminating the cgo dependency, but I'm hoping to gain some more insight in the meantime...

Matthew Zimmerman

unread,
Aug 6, 2015, 6:32:48 AM8/6/15
to Levi Corcoran, golang-nuts

In code, follow your allocations that are around too long.  Make sure you are actually releasing references to them.

One that bit me was a []byte to string conversion. The string uses the []byte as backing memory, so any slice of that string keeps the entire []byte around.


On Thu, Aug 6, 2015, 1:30 AM Levi Corcoran <all...@gmail.com> wrote:
Using pprof to troubleshoot memory leaks, we've isolated some types that are surviving GC much longer than expected.  The tooling is great for identifying the source of allocations, but I'm having a hard time figuring out why these are still referenced/rooted and are not being GC'd.  I've implemented a mechanism to capture heap dumps via runtime/debug.WriteHeapDump(), and since we're on Go 1.4.2 I've tried using heapdump14 to analyze the dump, but sadly that's failing due to some cgo usage (issue here).

Are there any other tools for analyzing 1.4 heap dumps, or other strategies for identifying what is still referencing types we wouldn't expect to stick around after a GC?  We're investigating the feasibility of eliminating the cgo dependency, but I'm hoping to gain some more insight in the meantime...

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Levi Corcoran

unread,
Aug 6, 2015, 1:19:12 PM8/6/15
to golang-nuts, all...@gmail.com
Thanks for the pointer on the []byte to string conversion; we had mentally followed all code paths and the references *should* have been released (thus our quandary / desire to inspect the heap for more info) - but we may have overlooked retained references masked by string conversion.  We'll take another look, but it'd be great to have tooling like heapdump14 or anything else similar as another option.  I certainly don't suspect a GC bug or anything like that, but it's a fairly complex system and knowing what's retaining the reference would be very helpful.

Dan Kortschak

unread,
Aug 6, 2015, 1:40:16 PM8/6/15
to Matthew Zimmerman, Levi Corcoran, golang-nuts
This would make strings mutable. Subslices of a string have this behaviour, but []byte -> string conversions don't (unless you are doing unsafe conversion)

http://play.golang.org/p/Wiin30dcfC

Matthew Zimmerman

unread,
Aug 6, 2015, 1:50:11 PM8/6/15
to Dan Kortschak, Levi Corcoran, golang-nuts
You're right Dan, I meant string -> []byte and string slices but obviously wrote it the wrong way

Dan Kortschak

unread,
Aug 6, 2015, 2:07:05 PM8/6/15
to Matthew Zimmerman, Levi Corcoran, golang-nuts
That conversion direction gives the same result - there is a copy made and thus no pinning. Subslicing (any kind of slice or string) does have the effect of pinning though.
Reply all
Reply to author
Forward
0 new messages