-->

什么将线序列的行为呢?(What will the behaviour of line-seq be

2019-10-19 06:00发布

我想了解一个懒惰的序列的行为,如果我重复的进行doseq但稳守第一要素的一部分。

 (with-open [log-file-reader (clojure.java.io/reader (clojure.java.io/file input-file-path))]

    ; Parse line parse-line returns some kind of representation of the line.
    (let [parsed-lines (map parse-line (line-seq log-file-reader))
          first-item (first parsed-lines)]

          ; Iterate over the parsed lines
          (doseq [line parsed-lines]
            ; Do something with a side-effect  
          )))

我不想保留任何名单,我只是想执行与每个元素的副作用。 我相信,如果没有first-item就没有问题。

我有我的程序内存的问题,我想,也许保留在开始一个参考的东西parsed-line序意味着整个序列存储。

什么是这里定义的行为? 如果正在存储的序列,有没有采取对象的副本,使该序列的实现部分被垃圾收集一个通用的方法?

Answer 1:

序列保持发生在这里

...
(let [parsed-lines (map parse-line (line-seq log-file-reader))
...

行的文件中的序列正在懒惰地产生和分析,但在整个序列扶住,的范围内的let 。 这个序列在实现doseq ,但doseq是没有问题的,它不会做序列保持。

...
(doseq [line parsed-lines]
 ; Do something
...

你不一定会在意序列保持在一个let ,因为范围let是有限的,但在这里,想必你的文件大和/或你留的动态范围内, let一会儿,或者返回包含它的闭合在“做一些事情”一节。

需要注意的是握住序列的任何给定的元素,包括第一,不成立的序列。 术语头部保持是有点用词不当的,如果你认为头是如在序言“列表中的头”的第一​​要素。 问题是保持到该序列的参考。



Answer 2:

JVM将不会返回内存操作系统一旦成为Java堆的一部分,除非你将其配置不同的默认最大堆大小是相当大的(可用RAM的1/4,通常情况下)。 因此,如果你只遇到像模糊的问题“天哪,这占用了大量的内存”,而不是“嗯,JVM抛出一个OutOfMemoryError”,你可能只是还没有调整的JVM你会喜欢它的方式法案。 partition-by 有点急切,因为它在内存中包含一个或两个分区一次,但除非你的分区是巨大的,你不应该运行的这段代码堆空间。 尝试设置-Xmx100m ,或任何你认为对你的程序的合理的堆大小,看看你是否有问题。



文章来源: What will the behaviour of line-seq be?