2009-04-13 98 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

垃圾收集器对短期对象特殊的代码,他们是非常非常便宜的使用。基本上,偶尔所有可触及的年轻物体都会被标记出来,而其他所有物体都会一举被收回。