scala/scala — pull request #357 by davidandrzej (2012-04-05 18:16:40+00:00)
Title: Iterator.++ memory leak 

When Iterator.++() concatenates an iterator with the result of a call-by-name function argument, the resulting compound iterator holds the 'self' reference to the original iterator indefinitely. Chaining many iterators together then causes every individual iterator to remain in memory even after all of its elements have been consumed.

This can be unpleasant if you are using this functionality to construct a compound iterator over individual functions that, for example, materialize data from disk.

This contrived snippet causes a heap OutOfMemoryError for me, but is fixed by modifying Iterator to use a boolean flag instead of an "eq self" check in order to determine whether the elements of the original iterator have already been exhausted.

```scala
object IteratorOOM {
def main(args: Array[String]) {

var ctr = 0
iterExample.foreach{junkStringList =>
ctr += 1
if(ctr == 100) {
System.exit(0)
}
println("ctr = %d".format(ctr))}
}

def iterExample(): Iterator[List[String]] = {
val myList =
List.fill(2)(List.fill(1000000)("abcdefghijklmnopqrstuvwxyz"))
myList.iterator ++ iterExample
}
}
```

The patched version passes scala tests and handles "x ++ x", although it still suffers from the infinite recursion described in SI-3759. Is there some other tricky corner case that requires doing the "eq self" instead of using a boolean flag?