【问题标题】:Help! I get OutofMemory while Retrieving web pages帮助!检索网页时出现内存不足
【发布时间】:2009-10-05 13:07:50
【问题描述】:

我正在从网络上检索 HTML。我得到“java.lang.OutOfMemoryError: Java heap space (repl-1:3)"

;; fetch: URL -> String
;; fetch returns the string of the HTML url
(defn fetch [url]
   (with-open [stream (. url openStream)]
      (let [buffer (BufferedReader. (InputStreamReader. stream))]
        (apply str (line-seq buffer)))))

我认为问题在于 "apply str" 。有没有更简单的方法

  • 将缓冲的阅读器转换为字符串?
  • 或检索网页?

编辑:我需要检索

http://fiji4.ccs.neu.edu/~zerg/lemurcgi/lemur.cgi?g=p&v=or&v=measures&v=being&v=taken&v=against,&v=corrupt&v=public&v=officials&v=of&v=any&v=governmental&v=jurisdiction&v=worldwide.

【问题讨论】:

  • 是否有理由将此部分放在 clojure 中而不是 Java 中?
  • 我的整个项目都在clojure中。谢谢。
  • 我在多个项目中使用了完全相同的代码来获取并不慢的东西。你说的慢是什么意思?获取某个页面需要 10 秒吗?
  • 很抱歉我收到 java.lang.OutOfMemoryError: Java heap space (repl-1:3)

标签: java clojure buffer


【解决方案1】:

哎呀。 line-seq 将每行创建一个 String 对象,然后您最终将其连接并丢弃,这将是缓慢而痛苦的。像这样使用apply 会将所有这些字符串放入一个巨大的列表中并在上面调用str,这也会很痛苦。

试试这个:

(use 'clojure.contrib.duck-streams)  ;SO's syntax highlighting sucks
(slurp* (reader url))

slurp* 使用 StringBuilder,这是在 Java 中构建大字符串的更好方法。

【讨论】:

    【解决方案2】:

    “太慢”是什么意思?我无法想象语言会很重要,因为这里的瓶颈是互联网。

    【讨论】:

    • 很抱歉我收到 java.lang.OutOfMemoryError: Java heap space (repl-1:3)
    • @tomjen:巧妙地连接平均长度为 M 的 N 个字符串的列表将复制 O(NNM) 个字节。相比之下,下载将涉及复制 O(N*M) 个字节。现在比例常数很重要,但是对于足够大的 N,字符串连接将比下载花费更长的时间。这是算法问题……不是语言问题。
    • PS,我可以拼写“naive”……我就是不会打字 :-)
    【解决方案3】:

    堆的当前大小是多少?您可以使用 JVM 参数通过 -X 参数指定更多堆空间。

    请参阅JVM Tuning 了解更多信息。如果您有更多时间,请尝试使用 Java Profiler 查看您的应用程序内存不足的原因。虽然,您可以调整堆空间的大小,但这是一个临时解决方案。

    【讨论】:

      【解决方案4】:

      有两种可能:

      1. 您正在获取的内容的大小占可用堆空间的很大一部分,并且您的算法在读取/连接过程中需要工作存储大小的 2 或 3 倍。在这种情况下,增加堆空间是一种合理的解决方法。

      2. 该算法实际上是使用 O(N^2) 空间来使用apply 进行连接。 apply 的实现是递归的,并且 clojure 编译器/JIT 编译器正在生成递归代码,其中包含大量对中间字符串的引用,这并非不可想象。在这种情况下,增加堆空间是一个糟糕的解决方法。

      无论哪种方式,我都会先用更有效的替代方案替换(apply str (line-seq buffer))(请参阅@Brian 的回答,以及我对@tomjen 的回答的评论)......如果它仍然是一个问题,只担心堆使用. (我怀疑它不会。)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2023-03-26
        • 1970-01-01
        • 1970-01-01
        • 2022-01-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多