-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
expandDeep uses unbounded queue which results in OutOfMemoryException #3411
Comments
Supplier<List<Byte>> genBytes = () -> Arrays.asList(new Byte[1024*1024*100]);
Flux.just(genBytes.get()).subscribe(); // OOM Hmm maybe Like above, |
@injae-kim strange, genBytes() generates 1gb byte array which shouldn't cause oom, how much memory do you have set as maximum, you can modify it to generate less memory, the point of this issue still lays in expandDeep which internally is using unbounded queue |
oh I see. I checked that My Ideapublic final Flux<T> expandDeep(Function<? super T, ? extends Publisher<? extends T>> expander, int capacityHint,
int maxCapacity, BiConsumer<? super Queue, ? super T> onMaxCapacity) { // 👈👈
return onAssembly(new FluxExpand<>(this, expander, false, capacityHint, maxCapacity, onMaxCapacity));
}
// e.g.
Flux.just(..)
.expandDeep(publisher -> .., ccapacityHint,
maxCapacity: 1024,
onMaxCapacity: (queue, elem) -> { /* just drop or replace last element, ..*/ } // 👈👈 If we use or, we can just simply drop new element when queue/deque reaches Hi @OlegDokuka , can you share your opinion please? 🙇 |
@injae-kim thanks for taking the time to analyze this issue 👏 I am to be honest a bit blurry about practical applications of this and wonder what sort of algorithms can be implemented on top of a bounded capacity variant that includes a strategy for dealing with overflows. If there's a practical use for it, I suppose we can base the actual design on the use cases instead of first designing and then considering what can be done with that :) Thanks in advance for providing use cases that are currently impossible and what could be the usage of a bounded capacity-based implementation, regardless of the final design -> we can see what the final requirements are once we see what the overflow strategies dictate. |
Closing due to inactivity for a month. Please reopen in case there's feedback to the above. |
@chemicL my concrete problem was caused by fast producer while having slow consumer (this happened in production system processing big chunks of data) , not sure if having strategy is a good use case, from my point of view just having maxCapacity option for such use cases as mine would suffice, so that in case the producer hits queue capacity limit it would wait for the consumer to empty the queue before inserting new object to queue |
Hey, @troydm. I missed your comment in this issue. From what you say this means that the standard mechanisms of reactive programming should prevent such a case, which would be the natural backpressure mechanism. Once the producer is signalled it can produce, it will. Having a bound on the queue means that at some point if the producer was asked to produce more, but the queue in the middle is full, something needs to happen - e.g. discarding the newly produced data. There's no means to delay on the producer side - the delay is a consequence of having no |
expandDeep uses unbounded queue internally which results in OutOfMemoryException when subscriber is not fast enough to keep up with publisher
Expected Behavior
not sure
Actual Behavior
OutOfMemoryException thrown
Steps to Reproduce
Possible Solution
add variety of expand and expandDeep methods with bounded queue in order to limit memory usage
Your Environment
netty
, ...):java -version
): 11uname -a
): Windows 10The text was updated successfully, but these errors were encountered: