0

我正在学习 Clojure,我想知道为什么我的应用程序会消耗这么多内存,并且在使用这些数据结构完成后不释放它。我想在 Clojure 中有一些我不知道的东西是让应用程序错误地持有一些东西。

这是一个简单的缩略图应用程序。它从一个目录中获取图像,调整它们的大小并将它们放入另一个目录。它使用javax.imageiojava.awt.image库。

(def thumb "path to thumbnails directory")

(defn get-thumb-filename [thumb-dir filename width]
  (str thumb-dir (fs/name filename) "_" width ".jpg"))

(defn get-thumb-filename-100 [filename]
  (get-thumb-filename thumb filename 100))

(defn small-thumbnail [filename]
  (make-thumbnail filename (get-thumb-filename-100 filename) 100))

(defn make-thumbnail [filename new-filename width]
  (let [img (javax.imageio.ImageIO/read (as-file filename))
        imgtype (java.awt.image.BufferedImage/TYPE_INT_ARGB)
        width (min (.getWidth img) width)
        height (* (/ width (.getWidth img)) (.getHeight img))
        simg (java.awt.image.BufferedImage. width height imgtype)
        g (.createGraphics simg)]
    (.drawImage g img 0 0 width height nil)
    (.dispose g)
    (javax.imageio.ImageIO/write simg "png" (as-file new-filename))))


;; `images` is a list of original filenames
;; Kick it off with...
(pmap small-thumbnail images)

此代码是 Noir 视图的一部分,这意味着在处理完所有图像后应用程序不会退出。

当我运行这段代码时,我的电脑开始发疯。风扇声音很大,主要的 java 进程使用了​​超过 1GB 的内存。处理完所有图像后,CPU 使用率下降到 < 5%,但内存使用率保持不变。

我怎样才能让它释放它显然不需要任何东西的所有这些内存?

谢谢!

PS:如果您需要我填写任何详细信息,请告诉我。

4

2 回答 2

3

JVM 管理它自己的内存。一旦它从操作系统获取内存,它通常不会将其归还。(或者至少我从未见过 Sun 的 JVM 这样做,可能有一些方法可以强制它......)

无论如何,使用您可能已经安装的工具来查看您的程序是否真的泄漏内存的一种简单方法是将 JConsole 附加到您的 JVM 并仅监视堆使用情况。查看活动监视器不会告诉您任何有用的信息。

http://java.sun.com/developer/technicalArticles/J2SE/jconsole.html

于 2012-08-05T14:44:51.560 回答
2

如果您在 repl 中执行此操作,则将pmap存储结果以*1供您以后使用;这不会在生产中发生,您可以在 repl 中阻止它发生,例如,(dorun (pmap ...)).

于 2012-08-04T23:41:29.187 回答