Sarebbe questo causare problemi di Garbage Collection
-
09-09-2019 - |
Domanda
ho scritto un po 'di Linq come DSL in cima Google Collezioni
public class IterableQuery {
public static <T> Where<T> from(Iterable<T> originalCollection) {
return new Where<T>( Iterables.transform(originalCollection, IterableQuery.<T>SAME()));
}
private static <T> Function<T, T> SAME() {
return new Function<T, T>(){
public T apply(T arg0) {
return arg0;
}
};
}
public static class SelectOrderBy<T>{
private final Iterable<T> iterable;
public SelectOrderBy(Iterable<T> iteable) {
this.iterable = iteable;
}
public SelectOrderBy<T> orderyBy( Comparator<T> sort ){
Ordering.forComparator(sort).sort((List< ? extends T>) iterable);
return new SelectOrderBy<T>( iterable);
}
public <F> Iterable<F> select( Function<? super T,? extends F> function){
return Iterables.transform(iterable, function);
}
public Iterable<T> selectEveryThing( ){
return iterable;
}
}
public static class Where<T>{
private final Iterable<T> iterable;
public Where(Iterable<T> iterable) {
this.iterable = iterable;
}
public SelectOrderBy<T> where(Predicate<T> predicate) {
return new SelectOrderBy<T>( Iterables.filter(iterable, predicate));
}
}
}
così ho potuto fare collezioni di query in modo leggibile più conciso
Iterable<? extends NewOrder > currentlyAssigned =
IterableQuery.
from(orders).
where(placedInLast10Days).
orderBy(lastName).
select(orderToNewOrder);
Sono preoccupato se questo approccio causerà un'esplosione di mini oggetti e causare alcuni problemi di Garbage Collection (o qualsiasi altra questione)?
Soluzione
Credo che Google utilizza Collezioni esecuzione differita per la maggior parte dei suoi iteratori. esecuzione differita ridurrebbe al minimo il numero di oggetti intermedi creati come sarebbe eliminare la maggior parte delle liste intermedi / temporaneo che potrebbero essere creati per ogni chiamata (dove, orderby, ecc).
In sostanza, l'ogni elemento restituito da currentlyAssigned.iterator () non viene calcolato fino a quando si chiama iterator.next (). Fino ad allora, la tua currentlyAssigned iterabile è solo un insieme di operazioni, niente di più.
La vostra unica preoccupazione per l'esplosione di mini-oggetti se tali oggetti durano più a lungo rispetto alla durata di una singola operazione elemento ... l'utilizzo della memoria di picco potrebbe ottenere abbastanza grande in quel caso e si potrebbe potenzialmente a corto di memoria molto grande liste o se si stesse convertendo gli oggetti (ad esempio chiamando ToUpper () su tutte le stringhe o qualcosa del genere). Questo sarebbe solo il caso se il risultato di dove () è stato un altro elenco, quindi orderby () ha creato un altro elenco, così via e così via.
Per quanto riguarda la gestione di molti oggetti vissuti brevi GC, non c'è nessun problema. Il moderno Java garbage collector pesantemente ottimizzato per gestire tale comportamento esatto.
Altri suggerimenti
Credo che dipende da come si comporta trasformare, se come un filtro pigro, vale a dire non si collega un riferimento a ogni risultato. poi contare saggio il suo oggetto più di OK. garbage collection saggio, non stanno mantenendo i riferimenti nascosti, una volta che si perde il riferimento principale l'intero grafico diventa irraggiungibile e viene raccolto. strada da percorrere l'uomo questo è davvero bello.
Il garbage collector ha codice speciale per gli oggetti di breve durata, e sono molto molto economico da usare. Fondamentalmente tanto tutti oggetti giovani raggiungibili sono assegnati ed ogni altro oggetto venga recuperato in un sol.