【问题标题】:Would this cause Garbage Collection issues这会导致垃圾收集问题吗
【发布时间】:2009-04-13 17:58:46
【问题描述】:

我在Google Collections之上写了一个类似DSL的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);

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

【问题讨论】:

  • 垃圾收集问题?我用托管语言编程,不用担心 :)

标签: java garbage-collection guava


【解决方案1】:

我相信 Google Collections 的大多数迭代器都使用延迟执行。延迟执行将最大限度地减少创建的中间对象的数量,因为它将消除可以为每个调用(where、orderby 等)创建的大部分中间/临时列表。

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

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

就 GC 处理许多短期对象而言,没有问题。现代 Java 垃圾收集器经过大量优化以处理该确切行为。

【讨论】:

  • 确认我们的迭代器总是尽可能地懒惰,如果您认识编写大部分迭代器的人,这不会让您感到惊讶!
【解决方案2】:

我认为这取决于转换的行为方式,如果它像一个惰性过滤器,即您不会为每个结果附加引用。那么它的数量超过了OK对象。垃圾收集明智,您不会保留任何隐藏的引用,一旦丢失根引用,整个图将变得无法访问并被收集。伙计,这真是太棒了。

【讨论】:

    【解决方案3】:

    垃圾收集器有专门的短寿命对象代码,使用起来非常便宜。基本上偶尔会标记所有可到达的年轻对象,然后一举回收所有其他对象。

    【讨论】:

      猜你喜欢
      • 2012-05-21
      • 2023-03-19
      • 1970-01-01
      • 2019-01-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-05-04
      相关资源
      最近更新 更多