好的,我看看能不能解释一下。
我有一些代码将 Java 迭代器(来自 Hadoop,碰巧)包装在 Scala Stream 中,因此我无法直接控制的客户端代码可能会多次读取它。使用此 Stream 完成的最后一件事是 reduce() 操作。Stream 会记住它已经看到的所有项目。不幸的是,在某些情况下迭代器会非常大,因此将所有项目存储在其中会导致内存不足错误。但是,一般来说,客户端代码需要多次迭代工具的情况与内存破坏迭代器的情况不同,如果确实存在这种情况,那不是我的问题。
我要确保的是我可以为需要它的代码提供记忆功能,但不能为不需要它的代码提供记忆功能(特别是对于根本不查看 Stream 的代码)。
Stream 中 reduce() 的代码说,它的编写方式允许对 Stream 的已访问部分进行 GC,同时减少。所以如果我能确保这真的发生,我会没事的。但在实践中,我如何确保发生这种情况?特别是,如果函数 A 创建流并将其传递给函数 B,函数 B 将流传递给函数 C,然后函数 C 调用 reduce(),那么函数 A、B 和 C 中仍然对流的引用呢? ? 在所有这些情况下,这三个函数中的任何一个都不会进一步使用流,尽管调用不一定是尾递归的。JVM 是否足够聪明,可以确保在调用 reduce() 时,函数 A、B 和 C 的引用计数为 0,从而可以发生 GC?本质上,这意味着 JVM 在函数 A 中注意到它对项目所做的最后一件事是调用函数 B,因此它在调用 B 的同时消除了自己的句柄,
如果这能正常工作,如果 A、B 或 C 有一个局部变量持有该项目,它是否也能工作?(同样,以后不会使用它。)那是因为在不使用本地变量的情况下正确编码会更加棘手。