Hello,
I have a testcase cut down from a larger application that leaks memory with
--gc:orc but does not leak memory with --gc:refc. The testcase uses the Decimal
library from Nimble.
Are there steps that library providers need to take to support --gc:orc ? What
should I investigate to determine if the issue is in the Decimal libarary or in
the nim compiler ?
The testcase below leaks memory from the collect() macro when using nim v1.6.6
(git hash 0565a70eab02122ce278b98181c7d1170870865c) on Ubuntu 18.0.4:
import strutils, strformat
import decimal/decimal
import sugar
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
proc getrusage*(who: RusageWho, usage: var Rusage) {.importc, header:
"sys/resource.h".}
proc main() =
let constDcm = newDecimal("0.15")
var newRange = collect(for x in 0..<10000: constDcm + 1)
var ru: Rusage
getrusage(RusageSelf, ru)
let initRss = ru.ru_maxrss
var lastRss = initRss
let prInterval = 100
for i in 0..<1000:
# Operation which leaks memory with --gc:orc,
# but does not leak memoryy with --gc:refc
# Note - need the add operation with
# a Decimal in collect() below
newRange = collect(for x in 0..<10000: constDcm + 1)
# Attempt to reclaim memory
GC_fullCollect()
# Check memory consumption
getrusage(RusageSelf, ru)
if ru.ru_maxrss > 100 * initRss:
raise newException(ValueError,"\n\n!!!!! Leaking Memory
!!!!!\n\n")
# Periodically print stats on memory consumption
if i mod prInterval == 0:
echo &"\nGC_getStatistics():\n{GC_getStatistics()}"
var incRss = ru.ru_maxrss - lastRss
lastRss = ru.ru_maxrss
echo &"Max RSS {ru.ru_maxrss}, Incremental max RSS: {incRss}
for {prInterval} iterations"
echo()
when defined(nimTypeNames):
dumpNumberOfInstances()
echo()
echo "\n\n###### No Memory Leak ######\n\n"
when isMainModule:
main()
Run