2009-04-13 155 views
0

我寫了一個小的LINQ像DSL上的Google Collections這會導致垃圾收集問題

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

垃圾收集問題?我在託管語言程序不擔心:) – 2009-04-13 18:03:03

回答

3

我相信Google Collections對其大部分迭代器都使用延遲執行。延遲執行會減少創建的中間對象的數量,因爲它會消除可能爲每個調用創建的大部分中間/臨時列表(where,orderby等)。

基本上,在調用iterator.next()之前,不會計算由nowAssigned.iterator()返回的每個元素。在此之前,您當前分配的迭代只是一組操作,僅此而已。

您對微型物體的爆炸唯一關心的,如果這些對象持續超過一個單一的元素操作的持續時間更長......峯值內存使用量可以得到在這種情況下,相當大的,你可能會在很耗盡內存大的列表或者如果你正在轉換對象(即在所有字符串或其他東西上調用ToUpper())。如果where()是另一個列表的結果,那麼orderby()會創建另一個列表,如此等等,這隻會是這種情況。

至於GC處理許多短暫的物體,沒有問題。現代Java垃圾收集器經過大量優化以處理確切的行爲。

+2

證實了我們的迭代器總是儘可能地偷懶,如果你知道是誰寫的大部分的傢伙這不會令你感到驚訝! – 2009-11-06 10:07:03

1

我認爲這取決於變換的行爲,如果它像一個懶惰的過濾器,即你不附加每個結果的引用。那麼它的不止是OK的對象。垃圾收集明智,你沒有保留任何隱藏的引用,一旦你失去了根引用整個圖形變得無法訪問和收集。走這條路真的很整齊。

0

垃圾收集器對短期對象特殊的代碼,他們是非常非常便宜的使用。基本上,偶爾所有可觸及的年輕物體都會被標記出來,而其他所有物體都會一舉被收回。