2009-04-13 5 views
0

Я написал небольшую Linq, как DSL на вершине Google CollectionsБудет ли вопросы эта причина Garbage Collection

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

} 

, так что я мог бы сделать коллекции запросов в более краткой читаемым образом

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

Я обеспокоен ли этот подход вызовет взрыв мини-объектов и вызовет некоторые проблемы с сборкой мусора (или любые другие проблемы)?

+1

Вопросы по сборке мусора? Я программирую на управляемом языке, чтобы не беспокоиться об этом :) –

ответ

3

Я считаю, что Google Collections использует отложенное выполнение для большинства своих итераторов. Отсроченное выполнение минимизировало бы количество промежуточных объектов, созданных таким образом, чтобы исключить большую часть промежуточных/временных списков, которые могут быть созданы для каждого вызова (где, orderby и т. Д.).

В принципе, каждый элемент, возвращаемый currentAssigned.iterator(), не вычисляется до тех пор, пока вы не вызовете iterator.next(). До тех пор, ваш nowAssigned iterable - это всего лишь набор операций, не более того.

Ваша единственная забота о взрыве мини-объектов, если эти объекты продолжаются дольше, чем продолжительность операции с одним элементом ... использование пиковой памяти в этом случае может стать довольно большим, и вы могли бы на самом деле вырваться из памяти на очень большие списки или если вы конвертируете объекты (т. е. вызываете ToUpper() для всех строк или что-то еще). Это было бы только в том случае, если результат where() был другим списком, затем orderby() создал другой список, так далее и т. Д.

Что касается GC, обрабатывающего много короткоживущих объектов, проблем нет. Современный сборщик мусора Java сильно оптимизирован для обработки этого точного поведения.

+2

Подтверждено, что наши итераторы всегда настолько ленивы, насколько это возможно, что не удивило бы вас, если бы вы знали парня, который написал большинство из них! –

1

Я думаю, что это зависит от того, как ведет себя преобразование, если оно похоже на ленивый фильтр, т. Е. Вы не прикрепляете ссылку на каждый результат. то его более чем объект подсчета объектов считается разумным. Мусорная сборка мудрая, вы не храните никаких скрытых ссылок, как только вы потеряете корневую ссылку, весь график становится недоступным и собирается. Путь к человеку это действительно опрятно.

0

Сборщик мусора имеет специальный код для короткоживущих объектов, и они очень дешевы в использовании. В принципе время от времени все достижимые молодые объекты отмечаются, и каждый другой объект рекуперируется одним махом.