I have a Nim application that hits OOM limits on Linux. I would like to know what objects are taking up all of that memory so I know what to modify.
What would be the recommended way to debug this?
Application is compiled with mm:orc
I saw references to a Heap Dump in old versions of the nim manual (https://nim-lang.org/1.0.6/gc.html), but it doesn't appear in the current version (https://nim-lang.org/1.6.10/mm.html), which I believe is due to the change to ORC.
Any help is appreciated
When on Linux: compile with --debugger:native -d:useMalloc, put in a quit() somewhere and run your program on valgrind; when the process exists valgrind will tell you exactly which memory has been allocated where.
Example:
type Foo = ref object
val: int
proc flop() =
var f = Foo(val: 42)
quit 0
flop()
nim c --debugger:native -d:useMalloc t.nim && valgrind --leak-check=full ./t
==906412== HEAP SUMMARY:
==906412== in use at exit: 24 bytes in 1 blocks
==906412== total heap usage: 1 allocs, 0 frees, 24 bytes allocated
==906412==
==906412== 24 bytes in 1 blocks are definitely lost in loss record 1 of 1
==906412== at 0x48407B4: malloc (vg_replace_malloc.c:381)
==906412== by 0x10AE7C: allocImpl__system_1768 (malloc.nim:5)
==906412== by 0x10AE8A: allocSharedImpl (malloc.nim:34)
==906412== by 0x10F62D: alignedAlloc__system_1908 (memalloc.nim:331)
==906412== by 0x112666: nimNewObjUninit (arc.nim:84)
==906412== by 0x1137E4: flop__t_5 (t.nim:8)
==906412== by 0x1138AA: NimMainModule (t.nim:11)
==906412== by 0x1138B3: NimMainInner (t.nim:30)
==906412== by 0x1138C1: NimMain (t.nim:41)
==906412== by 0x1138DE: main (t.nim:49)
==906412==
==906412== LEAK SUMMARY:
==906412== definitely lost: 24 bytes in 1 blocks
==906412== indirectly lost: 0 bytes in 0 blocks
==906412== possibly lost: 0 bytes in 0 blocks
==906412== still reachable: 0 bytes in 0 blocks
==906412== suppressed: 0 bytes in 0 blocks
==906412==
==906412== For lists of detected and suppressed errors, rerun with: -s
==906412== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
I haven't found my problem yet but the valgrind suggestion works and looks like it will help.
Running a series of tests and I'll analyze the valgrind results in the morning.
Thanks, @zevv!
+1 for valgrind, dead simple usage.
All my tests were passing until I added valgrind and it caught bunches of mem leaks
A few weeks ago I made this little tool for fun to visualize memory usage for multi threaded programs: it injects a little LD_PRELOAD lib overriding malloc() and friends and draws all allocations in a 2D hilbert projection of the heap; nice to get a "feel" of what your program is doing, also fun to watch and compare different GC implementations at work, for example: