-
Notifications
You must be signed in to change notification settings - Fork 608
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Memory leak #1625
Comments
I have ran the JVM with JFR recording enabled and pushed the resulting recording in the GitHub project I mentioned above. |
Ok, I managed to reproduce the issue with this dead simple code. object StreamPlayground extends App {
def range[F[_]](start: Long, stopExclusive: Long, by: Long = 1L): Stream[F, Long] =
Stream.unfold(start) { i =>
if ((by > 0 && i < stopExclusive && start < stopExclusive) ||
(by < 0 && i > stopExclusive && start > stopExclusive))
Some((i, i + by))
else None
}
println(range[Pure](10000004704L, 10002805638L)
.fold(0L)(_ + _)
.compile
.last)
} I had to copy the implementation of This code needs no less than 1.4 GB of heap to run, and profiling shows crazy high GC pressure, as well as the same allocation pattern as the one I obtain with my diff pipe implementation.
|
Does your |
Well, as I said, 1.4 GB of heap is the minimum necessary to not run out of memory. Since I expect such a simple streaming program to use a hundred times less, I can say that, yes, it outright runs out of memory :). Now if you're asking whether the crash depends on the upper bound, it appears so, since I multiplied the one I give as an example by two, and then 1.4 GB were no longer sufficient. |
For now I'll resort to using eagerly allocated ranges. In my case, it means pre-allocating 16 MB, but it's ok. I'm still stuck because of #1624 though. |
I wonder if this (and #1624) are related to @mpilquist's recent scoping changes with |
I don't know how recent are the changes you're mentioning, but know that the problems I raised in this issue and #1624 were first observed in version 1.0.5. I upgraded to 2.0.0 afterwards, hoping the problems were fixed. |
That definitely rules out the recent changes then. This is weird and concerning, because it implies that |
It's not println(Stream.range(0, 2800934).compile.last) As-is: println(Stream.range(0, 2800934).map(_ + 1).compile.last) These two fail though: println(Stream.range(0, 2800934).fold(0L)(_ + _).compile.last)
println(Stream.range(0, 2800934).forall(_ >= 0).compile.last) It appears that the recursive pulls are holding on to the intermediate values for some reason. |
Oh wait wait, I remembered wrong. I just retried the small code above with 1.0.5 and Sorry to have misled you. |
Thanks for the update. The fact that this is new in 2.0.0 makes me suspect something in the Any ideas @diesalbla? I'm starting a git bisect now... |
I did a git bisect between 2.0.0 tag (bad) and 1.0.5 tag (good). My test procedure was starting SBT with
Looks like leak was introduced by 36b1279 |
@mpilquist Could you try again that check on the tip of this branch? #1630 |
Yep will do. |
Confirmed fixed by #1630. I'll get a 2.0.1 release out this weekend. |
Great ! Thanks guys. |
@epellizzer I just released 2.0.1 -- please give it a try and let us know how it goes. |
Cool. I will try next week. Thanks ! |
I confirm everything is OK with 2.0.1. |
Hi.
I have written a
Pipe2
that computes a diff between two sorted streams, and it seems to cause a memory leak that in some cases leads to the heap blowing up.To ease everyone's life, I have created this GitHub project that contains the commented code as well as the unit tests that show the problem.
It was the first time I wrote a
Pipe2
, so I hope my implementation is not too naive, but even so, FS2 should probably not react that way.The text was updated successfully, but these errors were encountered: