That's quite platform-dependent, and even the notion of "memory usage" is pretty vague in a modern OS with virtual memory. The size of the malloc heap is usually the most useful, I've found; more generally it's the amount of address space that's unshared and mapped as writeable. Utilities like 'top' or macOS's Activity Monitor can show that as a live value you can monitor.
I'm not sure the Nim APIs above will be as accurate because I think they only report on memory allocated by Nim itself. If you're using any native libraries it probably won't include memory they allocate.
If you're on macOS (the only platform I know well), the heap tool is very useful. It reports a process's heap usage and breaks it down by the size of the blocks. It can also identify Objective-C, CoreFoundation and [some] C++ objects and group them by class name, which is useful if you're using system frameworks. Check the man page for details.
system.getTotalMem + friends have their use but as mentioned they're not monitoring everything, eg calls to malloc etc.
I'm surprised noone mentioned getrusage. I'd like an API getResourceUsage that wraps it in a platform-independent way, see https://github.com/timotheecour/Nim/issues/446
Perhaps getResourceUsage could report also other things besides what's reported in getrusage.
I use getrusage on POSIX but is there an equivalent in Windows?
Wrapper: https://github.com/mratsim/weave/blob/e5a3701/benchmarks/resources.nim
type
Timeval {.importc: "timeval", header:"<sys/time.h>", bycopy.} = object
Rusage* {.importc: "struct rusage", header:"<sys/resource.h>", bycopy.} = object
ru_utime {.importc.}: Timeval
ru_stime {.importc.}: Timeval
ru_maxrss* {.importc.}: int32 # Maximum resident set size
# ...
ru_minflt* {.importc.}: int32 # page reclaims (soft page faults)
RusageWho* {.size: sizeof(cint).} = enum
RusageChildren = -1
RusageSelf = 0
RusageThread = 1
when defined(debug):
var H_RUSAGE_SELF{.importc, header:"<sys/resource.h".}: cint
var H_RUSAGE_CHILDREN{.importc, header:"<sys/resource.h".}: cint
var H_RUSAGE_THREAD{.importc, header:"<sys/resource.h".}: cint
assert H_RUSAGE_SELF == ord(RusageSelf)
assert H_RUSAGE_CHILDREN = ord(RusageChildren)
assert H_RUSAGE_THREAD = ord(RusageThread)
proc getrusage*(who: RusageWho, usage: var Rusage) {.importc, header: "sys/resource.h".}
Usage, for example for nqueens parallel benchmark
when not defined(windows):
var ru: Rusage
getrusage(RusageSelf, ru)
var
rss = ru.ru_maxrss
flt = ru.ru_minflt
init(Weave)
when not defined(windows):
let start = wtime_msec()
let count = nqueens_par(n, 0, alloca(char, n))
when not defined(windows):
let stop = wtime_msec()
when not defined(windows):
getrusage(RusageSelf, ru)
rss = ru.ru_maxrss - rss
flt = ru.ru_minflt - flt
exit(Weave)
verifyQueens(n, count)
if not example_solution.isNil:
stdout.write("Example solution: ")
for i in 0 ..< n:
c_printf("%2d ", example_solution[i])
stdout.write('\n')
const lazy = defined(WV_LazyFlowvar)
const config = if lazy: " (lazy flowvars)"
else: " (eager flowvars)"
echo "Scheduler: Weave", config
echo "Benchmark: N-queens"
echo "Threads: ", nthreads
when not defined(windows):
echo "Time(us) ", stop - start
echo "Max RSS (KB): ", ru.ru_maxrss
echo "Runtime RSS (KB): ", rss
echo "# of page faults: ", flt
echo "Problem size: ", n,"x",n, " board with ",n, " queens"
echo "Solutions found: ", count
quit 0
is there an equivalent in Windows?
yes, see links in https://github.com/timotheecour/Nim/issues/446
We don't have to bloat os.nim but this could go under std/osprocutils.nim