2009-04-13 4 views
0

ich ein wenig Linq wie DSL oben auf Google CollectionsWürden diese Ursache Garbage Collection gibt

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)); 
     } 
    } 

} 

so schrieb ich Abfrage Sammlungen in einer prägnanten lesbaren Weise

Iterable<? extends NewOrder > currentlyAssigned = 
     IterableQuery. 
      from(orders). 
      where(placedInLast10Days). 
      orderBy(lastName). 
      select(orderToNewOrder); 

Ich mache mir Sorgen machen könnte, ob Dieser Ansatz führt zu einer Explosion von Miniobjekten und verursacht einige Garbage Collection-Probleme (oder andere Probleme)?

+1

Garbage Collection-Probleme? Ich programmiere in einer verwalteten Sprache, um mir keine Sorgen zu machen :) –

Antwort

3

Ich glaube, dass Google Collections die verzögerte Ausführung für die meisten Iteratoren verwendet. Die verzögerte Ausführung würde die Anzahl der erstellten Zwischenobjekte minimieren, da dadurch die meisten Zwischen-/Temporärlisten, die für jeden Aufruf erstellt werden könnten (wo, orderby usw.), eliminiert würden.

Grundsätzlich wird jedes Element, das von currentAssigned.iterator() zurückgegeben wird, nicht berechnet, bis Sie iterator.next() aufrufen. Bis dahin ist Ihre aktuell zugewiesene iterable nur eine Reihe von Operationen, nicht mehr.

Ihre einzige Sorge über die Explosion von Mini-Objekten, wenn diese Objekte länger dauern als die Dauer einer einzelnen Element-Operation ... Spitzenspeichernutzung könnte in diesem Fall ziemlich groß werden und Sie könnten sehr viel Speicher auslassen große Listen oder wenn Sie Objekte konvertierten (zB Aufruf von ToUpper() für alle Strings oder so). Dies wäre nur dann der Fall, wenn das Ergebnis von where() eine andere Liste wäre, dann ordnet orderby() eine andere Liste an und so weiter und so fort.

Soweit der GC viele kurzlebige Objekte behandelt, gibt es kein Problem. Der moderne Java-Garbage Collector wurde stark optimiert, um genau dieses Verhalten zu handhaben.

+2

Bestätigt, dass unsere Iteratoren immer so faul wie möglich sind, was dich nicht überraschen würde, wenn du den Typ kennst, der die meisten geschrieben hat! –

1

Ich denke, es hängt davon ab, wie sich die Transformation verhält, wenn es wie ein Lazy-Filter ist, d. H. Sie fügen keinen Verweis auf jedes Ergebnis hinzu. dann ist es mehr als OK Objekt Anzahl weise. Garbage Collection weise keine verborgenen Referenzen mehr auf, sobald der Root-Verweis verloren geht, wird der ganze Graph unerreichbar und wird gesammelt. Weg zum Mann, das ist wirklich nett.

0

Der Garbage Collector hat einen speziellen Code für kurzlebige Objekte, und sie sind sehr, sehr billig zu verwenden. Grundsätzlich werden ab und zu alle erreichbaren jungen Objekte markiert und alle anderen Objekte auf einen Schlag zurückgewonnen.