Помогите! Я получаю OutofMemory при получении веб-страниц - PullRequest
1 голос
/ 05 октября 2009

Я получаю 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.

Ответы [ 4 ]

6 голосов
/ 06 октября 2009

Хлоп. line-seq собирается создать один String объект на строку, который вы затем в конечном итоге объединяете и отбрасываете, что будет медленно и мучительно. Подобное использование apply приведет к тому, что все эти строки попадут в огромный список и вызовет str для этого, что также будет болезненным.

Попробуйте вместо этого:

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

slurp* использует StringBuilder, который является лучшим способом построения большой строки в Java.

1 голос
/ 06 октября 2009

Есть две возможности:

  1. Размер содержимого, которое вы извлекаете, составляет значительную долю доступного пространства кучи, и ваш алгоритм требует в 2 или 3 раза больше размера рабочей памяти в процессе чтения / объединения. В этом случае разумным решением является увеличение пространства кучи.

  2. Алгоритм фактически использует пространство O (N ^ 2) для конкатенации, используя apply. Не исключено, что реализация apply является рекурсивной и что компилятор clojure / JIT-компилятор создает рекурсивный код с большим количеством ссылок на промежуточные строки. В этом случае увеличение пространства кучи - плохой обходной путь.

В любом случае, я бы начал с замены (apply str (line-seq buffer)) более эффективной альтернативой (см. Ответ @ Brian и мой комментарий к ответу @ tomjen) ... и беспокоился только об использовании кучи, если это все еще проблема , (Я подозреваю, что это не будет.)

1 голос
/ 06 октября 2009

Каков текущий размер кучи? Вы можете использовать аргументы JVM для указания большего пространства кучи с -X arg.

См. JVM Tuning для получения дополнительной информации. Если у вас есть больше времени, попробуйте использовать Java Profiler, чтобы понять, почему вашему приложению не хватает памяти. Хотя вы можете изменить размер кучи, это временное решение.

1 голос
/ 05 октября 2009

Что вы подразумеваете под "слишком медленным"? Я не могу себе представить, что язык будет иметь большое значение, поскольку узким местом здесь будет Интернет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...