-
Notifications
You must be signed in to change notification settings - Fork 7.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Scheduler.schedulePeriodically - memory leak #782
Comments
I updated the issue multiple times, hopefully it's helpful. |
Thanks. @benjchristensen are you working on this? |
I've just been hit by that while implementing a short-period periodic task using an I'm using 0.16.1 on Android. |
Yes I can as schedulers is on my list for 0.17 and I fixed memory leaks in schedulers already, obviously missing this one. I completely ignored the 'schedulePeriodically' methods. |
Hey, I believe this can be closed, no? I saw that Schedulers changed the interface. |
Yup it can be ... I need to do a pass through all of the issues, I bet 1/3 of them are probably ready for me to close. |
I think the current version doesn't leak but can't be cancelled either. This program prints 1 through 6. public static void main(String[] args) throws Exception {
Worker w = Schedulers.computation().createWorker();
CompositeSubscription cs = new CompositeSubscription();
AtomicInteger i = new AtomicInteger();
cs.add(w.schedulePeriodically(() -> {
int j = i.incrementAndGet();
if (j == 3) {
cs.unsubscribe();
}
System.out.println(j);
if (j == 6) {
w.unsubscribe();
}
}, 200, 200, TimeUnit.MILLISECONDS));
TimeUnit.SECONDS.sleep(2);
} The reason this doesn't seem to be an issue because most operators don't mix schedule with schedulePeriodic. |
Memory leak is fixed. The cancellation issue is being solved elsewhere. |
Folks, this is a pretty bad memory leak. The
schedulePeriodically
methods as currently defined are leaking.For example, let's start with the current code in rx.Scheduler, line 93.
The method in question is this:
The problem is that each and every one periodic execution of the given action is creating a new Subscription reference that is capturing the reference of the previous subscription. And no subscription reference will ever be garbage collected, unless unsubscribe() happens.
It's easy to reproduce the effect (i.e. OutOfMemoryError) with a simple test that will end up with an error in a matter of seconds:
Here's how that looks like in a profiler:
The above, because it doesn't use a
ScheduledExecutorService
, is using the defaultScheduler.schedulePeriodically
that I pasted above, which is pretty heavy. The problem is that even with aScheduledExecutorService
, it still leaks, because the ExecutorScheduler is still using aCompositeSubscription
and when scheduling anAction0
, this basically pushesSubscriptions.empty
over and over again into anArrayList
. Thus, the code is slower in leaking memory, but it still leaks.From what I can see, this affects all
schedulePeriodically
implementations and as a consequence, things likeObservable.interval
are anything but infinite.UPDATE: I now see that a pull request addressing some issues was made in #712 - in particular, it changed the behavior of ExecutorScheduler. I haven't tested this version, I will do so today hopefully.
However the default
Scheduler.schedulePeriodically
is still there and something to consider - if something that does periodic scheduling leaks, it probably shouldn't be there.The text was updated successfully, but these errors were encountered: