-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Closed
Labels
Description
Example
iterator test(): int {.closure.} =
for i in 0..<1000000:
var heavy: seq[int]
heavy = newSeq[int](10000)
yield heavy.len
GC_disableMarkAndSweep()
for i in test():
discardwill use a lot of memory, because the lines:
var heavy: seq[int]
heavy = newSeq[int](10000)will generate:
(*colonenvP_).heavy2 = (tySequence__qwqHTkRvwhrRyENtudHQ7g*)0;
asgnRef((void**) (&(*colonenvP_).heavy2), newSeq__eA9b5cYyFZe7gRm4F9aRTKlA(((NI) 10000)));which erases the last reference before calling asgnRef.
Assigning directly avoids this issue:
var heavy = newSeq[int](10000)
Because the heavy2 = 0 line is not generated, and asgnRef will call decRef on the last value.
Possible Solution
It seems that in regular procs, the var line will be translated to:
asgnRef((void**) (&fut__JYhQvJxHhtC8fq7FzTRUVQ), NIM_NIL);
asgnRef((void**) (&fut__JYhQvJxHhtC8fq7FzTRUVQ), testInner__bhBT5he32hyARROogQacKg());Since we assign to NIL instead of setting to 0 manually, the reference count is correctly updated
Additional Information
Happens both on 1.2.6 & devel.
Obviously, the mark & sweep will catch that, but as part of optimizing ram consumption in nimbus, we're trying to rely on it as little as possible