这会导致垃圾收集问题

时间:2009-04-13 17:58:47

标签: java garbage-collection guava

我在Google Collections

之上写了一个类似于Linq的Linq
    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);

我担心这种方法是否会导致迷你对象爆炸并导致一些垃圾收集问题(或任何其他问题)?

3 个答案:

答案 0 :(得分:3)

我相信Google Collections会对其大多数迭代器使用延迟执行。延迟执行将最小化创建的中间对象的数量,因为它将消除可为每个调用创建的大多数中间/临时列表(where,orderby等)。

基本上,在调用iterator.next()之前,不会计算currentAssigned.iterator()返回的每个元素。在此之前,您的currentAssigned iterable只是一组操作,仅此而已。

如果这些对象的持续时间超过单个元素操作的持续时间,那么你对迷你对象爆炸的唯一关注......在这种情况下,峰值内存使用量会变得非常大,你可能会在非常大的情况下耗尽内存列表或者您是否正在转换对象(即在所有字符串或其他内容上调用ToUpper())。只有当where()的结果是另一个列表,然后orderby()创建另一个列表时,才会出现这种情况,依此类推。

就GC处理许多短寿命物体而言,没有问题。现代Java垃圾收集器经过大量优化,可以处理这种确切的行为。

答案 1 :(得分:1)

我认为这取决于变换的行为方式,如果它像一个惰性过滤器,即你没有附加对每个结果的引用。然后它比OK对象更明智。明智的垃圾收集,你没有保留任何隐藏的引用,一旦你失去根引用,整个图形变得无法访问并被收集。去男人的方式这真的很整洁。

答案 2 :(得分:0)

垃圾收集器具有短期对象的特殊代码,使用起来非常便宜。基本上偶尔会标记所有可到达的年轻对象,并且一举夺回所有其他对象。