It's a combination of HotSpot and the way Scala's traits are implemented.
If I turn HotSpot off with -Xint
, Stream.filter
will also die with an OutOfMemoryException
. In the generated bytecode itself, this
and the variables rest
and these
are stored in different memory locations, but because this
is only used to initialize these variables I believe HotSpot is smart enough to simply reuse the memory location for this
. This explains why Stream.filter
does not run out of memory.
HotSpot's optimization to Stream.filter
should also apply to LinearSeqOptimized.find
, however because of the way traits are implemented a reference to this
is preserved. When a method is implemented inside of a trait, Scala compiles that method into a static method. When a class inherits from that trait, Scala creates a small stub method that invokes the static method. So even though HotSpot optimizes the static method for LinearSeqOptimized.find
the stub method's stack frame still has a reference to this
.