groupBy,Rx中的过滤器和内存泄漏

时间:2015-11-25 21:55:29

标签: java memory-leaks reactive-programming rx-java reactivex

根据groupBy的文件:

  

注意:GroupedObservable将缓存要发出的项目,直到订阅为止。因此,为了避免内存泄漏,您不应该忽略那些与您无关的GroupedObservable。相反,您可以向他们发出信号,告知他们可以通过向take(int)(0)这样的运算符应用来放弃缓冲区。

有一个RxJava tutorial,上面写着:

  

在内部,每个Rx操作员都做3件事

     
      
  1. 订阅源并观察值。
  2.   
  3. 它根据操作者的目的转换观察到的序列。
  4.   
  5. 通过调用onNext,onError和onCompleted,将修改后的序列推送给自己的订阅者。
  6.   

让我们看看下面的代码块,它只从range(0, 10)中提取偶数:

Observable.range(0, 10)
        .groupBy(i -> i % 2)
        .filter(g -> g.getKey() % 2 == 0)
        .flatMap(g -> g)
        .subscribe(System.out::println, Throwable::printStackTrace);

我的问题是:

  1. 这是否意味着filter运营商已经暗示订阅了groupByObservable<GroupedObservable>仅产生的每个群组?

  2. 在这种情况下是否会出现内存泄漏?如果是这样,

  3. 如何正确丢弃这些群组?将filter替换为自定义的take(0),其中return Observable.empty()后跟take(0)?您可能会问为什么我不能直接返回filter:因为groupBy在{{1}}之后不会立即跟进,但可以在任何地方链条涉及更复杂的条件。

2 个答案:

答案 0 :(得分:5)

除了内存泄漏之外,由于内部请求协调问题,当前的实现可能会完全挂起。

请注意,使用take(0),可以始终重新创建组。我改为使用ignoreElements来删除值,没有项目达到flatMap,并且该组本身不会一直被重新创建。

答案 1 :(得分:4)

您的怀疑是正确的,为了正确处理分组的observable,必须订阅每个内部可观察量(import java.io.File; import java.io.FileNotFoundException; import java.util.Scanner; public class Target { /*--------------LINKED LIST------------------*/ private Node head; private Node tail; public void add(int obj) { if (head == null) { head = new Node(obj); tail = head; } else { tail.next = new Node(obj); tail = tail.next; } } class Node { public Node next; public int item; public Node(int item) { this.item = item; } } /*--------------LINKED LIST------------------*/ public Target() { head = null; } public static void main(String args[]) throws FileNotFoundException { Scanner fileIn = new Scanner(new File("in.txt")); Target list = new Target(); while (fileIn.hasNext()) { list.add(fileIn.nextInt()); //Read the file into the linkedlist. } fileIn.close(); System.out.println(list.recursiveSolution(list, 0)); } public boolean recursiveSolution(Target list, int target) { return subsetSumXOR(list.head, 0, 0, target); } private boolean subsetSumXOR(Node node, long sumOne, long sumTwo, int target) { if (node == null) { return (sumOne ^ sumTwo) == target; //base case, when node is null we've reached the end of the list. } return subsetSumXOR(node.next, sumOne + node.item, sumTwo, target) || subsetSumXOR(node.next, sumOne, sumTwo + node.item, target); } } )。由于g订阅了外部可观察量,所以只是一个坏主意。只需使用filterflatMap中执行您需要的操作即可过滤掉不需要的群组。

ignoreElements