Mam java.lang.OutOfMemoryError: Java heap space
, gdy używam implementacji AbstractSpliterator
, która zgłasza nieznany rozmiar.Implementacja AbstractSpliterator z nieznanymi rozmiarami wyrzuca OutOfMemoryError: Przestrzeń sterty Java
W tym przypadku zdefiniowałem klasę StreamCollapse
, która rozszerza AbstractSpliterator
i łączy serię sąsiednich elementów w implementacji tryAdvance()
. Jego konstruktor nazywa super konstruktora jako super(Long.MAX_VALUE, source.characteristics())
.
Jeśli chodzi o API documentation, oczekiwałem, że użycie Long.MAX_VALUE
wskazuje nieznany rozmiar. Jednak wydaje się, że zamiast tego próbuje przydzielić pamięć o tym rozmiarze.
Dlaczego próbuje przydzielić to miejsce? Jaką wartość powinienem użyć dla szacowanego rozmiaru?
Tutaj jest przykład testu:
Stream<Integer> nrs = Stream.of(3, 3, 5, 5, 3, 3, 3, 4, 4, 4 ,5 , 5);
Integer [] expected = {3, 5, 3, 4, 5};
Object[] actual = collapse(nrs).toArray();
assertEquals(actual, expected);
i wdrożenie collapse()
metoda:
static <T> Stream<T> collapse(Stream<T> source) {
return StreamSupport.stream(
new StreamCollapse<T>(source.spliterator()), false);
}
class StreamCollapse<T> extends AbstractSpliterator<T> implements Consumer<T> {
private final Spliterator<T> source;
private T curr = null;
StreamCollapse(Spliterator<T> source) {
super(Long.MAX_VALUE, source.characteristics());
this.source = source;
}
@Override
public boolean tryAdvance(Consumer<? super T> action) {
T prev = curr;
boolean hasNext;
while ((hasNext = source.tryAdvance(this)) && curr.equals(prev)) { }
if(hasNext) action.accept(curr);
return hasNext;
}
@Override
public void accept(T item) {
curr = item;
}
}
To jest poprawna odpowiedź, spliterator * musi * wyczyścić cechy 'SIZED' i' SUBSIZED'. Jako uzupełnienie, dobrym sposobem byłoby użycie 'estimateSize()' ze źródłowego spliteratora jako oszacowanego rozmiaru filtrującego spliteratora. W końcu rzeczywisty rozmiar będzie wynosił od zera do tego rozmiaru źródła. Tak właśnie działa "filter", a obecna implementacja poradzi sobie z tym znacznie lepiej niż z zupełnie nieznanymi rozmiarami. – Holger
@Holger dziękuję za kontrolę mojej odpowiedzi. Dostaję również twoją sugestię. –