The default iteration interface can cause memory leak?

This is not a memory leak because Julia still release the memory if it got unused.

Julia’s iteration interface does not cause more memory assumption than other programming languages (Python/Java/C++/C#). Just like in other programming languages, Julia’s iterable object itself (xs in your example) should usually keep alive during the iteration, and a specified iteration interface creates a helper object (traditionally called iterator) to perform the following 4 operations:

  1. getiterator: create an iterator from the iterable object
  2. current: get the current element from the iterator
  3. movenext: move the iterator to the next
  4. hasnext: check if the iterator has ended

Java uses exactly 4 methods for the above 4 operations, C# and Python uses 2 methods (combine movenext, hasnext and current together).

Julia also uses 2 methods (iterate(itr) and iterate(itr, state)), which is not that different from those in other languages. This is to say, the following statement might not be appropriate:

state here can be regarded as the iterator, and we can implement the iteration interface for LinkedList this way:

# return iterator
function iterate(itr)
       if itr is empty
           return nothing
       else
           return (the first element, the second node of the linked list)
       end
end 

# hasnext + movenext + current
function iterate(itr #= unused =#, node)
     if node has next
         return (the value of the node, the next node)
     else
         return nothing
     end
end
#

Such implementation iterates LinkedLists in O(n) time.

Specifically, using above implementation, Julia is smart enough to not remain xs alive by inlining the code. As can be seen, the itr argument from iterate(itr, node) method is unused, hence disappear after inlined. If there is no use of itr after the iteration, Julia can release itr before stopping the iteration, if needed.

6 Likes