BerlinBrown napisał(a):
> I want to make it clear, that it probably isn't Clojure's memory
> problem but something with my code.
>
> Anyway, I was trying to figure out my heap memory goes up so much on
> various operations in my application.  Sure, it could be anything but
> I know I am doing something wrong.

I've been playing around recently with JMX in clojure in particular
in context of heap memory usage. I created some simple function
in Clojure and method in Java in order to be able to check
heap memory usage (see code below).
I used this code to check your function's memory consumption.
Then I implemented something similar in Java and checked that as
well.
My quick and dirty tests show that there is no difference between
Clojure
and Java version regarding memory usage in this case.
So maybe you're looking in wrong place.

$ clojure test_io.clj test.xml
TEST: test.xml (2,51MB)
used: 1,23MB, reserved: 1,94MB, max: 63,56MB
used: 13,89MB, reserved: 18,79MB, max: 63,56MB
$ clojure test_io.clj test2.xml
TEST: test2.xml (5,02MB)
used: 1,23MB, reserved: 1,94MB, max: 63,56MB
used: 26,93MB, reserved: 36,00MB, max: 63,56MB

$ java TestIO test.xml
TEST: test.xml (2,51MB)
used: 0,21MB, reserved: 1,94MB, max: 63,56MB
used: 13,20MB, reserved: 17,65MB, max: 63,56MB
$ java TestIO test2.xml
TEST: test2.xml (5,02MB)
used: 0,21MB, reserved: 1,94MB, max: 63,56MB
used: 26,24MB, reserved: 34,92MB, max: 63,56MB

# test_io.clj

(ns test_io
  (:import (java.io File FileInputStream InputStreamReader
LineNumberReader)
           (java.lang.management ManagementFactory MemoryType)))

(defn open-file [file-path]
  ;; Java oriented approach for opening file
  (let [stream (new FileInputStream file-path)
        instr (new LineNumberReader (new InputStreamReader stream))
        ;; Use type hints to ensure a character type.
        readBuffer #^"[C" (make-array (. Character TYPE) 2048)
        buf (new StringBuffer)]
    (loop [n (. instr read readBuffer)]
      (when (> n 0)
        (. buf append readBuffer 0 n)
        (recur (. instr read readBuffer))))
    (. instr close)
    (. buf toString)))

(defn memory-usage []
  (let [pools (ManagementFactory/getMemoryPoolMXBeans)
        mb (* 1024.0 1024.0)
        step (fn [pools tu tr tm]
               (if (not (seq pools))
                 [(/ tu mb) (/ tr mb) (/ tm mb)]
                 (let [pool (first pools)
                       usage (. pool getUsage)]
                   (recur (rest pools)
                          (+ tu (. usage getUsed))
                          (+ tr (. usage getCommitted))
                          (+ tm (. usage getMax))))))]
    (step (filter #(= (. % getType) MemoryType/HEAP) pools) 0 0 0)))

(defn dump-memory-usage [[used reserved max]]
  (println (format "used: %.2fMB, reserved: %.2fMB, max: %.2fMB"
                   used reserved max)))

(defn test-open-file [fname]
  (let [file (new File fname)]
    (println (format "TEST: %s (%.2fMB)" (. file getName)
                     (/ (. file length) (* 1024.0 1024.0))))
    (dump-memory-usage (memory-usage))
    (open-file (. file getAbsolutePath))
    (dump-memory-usage (memory-usage))))

(test-open-file (first *command-line-args*))


# TestIO.java

import java.util.List;
import java.util.Formatter;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.io.IOException;

import java.lang.management.ManagementFactory;
import java.lang.management.MemoryMXBean;
import java.lang.management.MemoryPoolMXBean;
import java.lang.management.MemoryUsage;
import java.lang.management.MemoryType;

public class TestIO
{
    private double MB = 1024.0 * 1024.0;

    public String openFile(String filePath) throws IOException
    {
        FileInputStream stream = new FileInputStream(filePath);
        LineNumberReader instr = new LineNumberReader(new
InputStreamReader(stream));
        char[] readBuffer = new char[2048];
        StringBuffer buf = new StringBuffer();

        int n = 0;
        while ((n = instr.read(readBuffer)) > 0)
        {
            buf.append(readBuffer, 0, n);
        }
        instr.close();
        return buf.toString();
    }

    public void testOpenFile(String fname) throws IOException
    {
        File file = new File(fname);
        System.out.println(String.format("TEST: %s (%.2fMB)",
                                         file.getName(),
                                         file.length() / MB));
        System.out.println(dumpMemory());
        openFile(file.getAbsolutePath());
        System.out.println(dumpMemory());
    }

    private String dumpMemory()
    {
        StringBuilder sb = new StringBuilder();

        long totalUsed = 0;
        long totalReserved = 0;
        long totalMax = 0;

        List<MemoryPoolMXBean> pools =
ManagementFactory.getMemoryPoolMXBeans();
        for (MemoryPoolMXBean pool : pools)
        {
            MemoryUsage usage = pool.getUsage();
            if (pool.getType() != MemoryType.HEAP)
            {
                continue;
            }
            totalUsed += usage.getUsed();
            totalReserved += usage.getCommitted();
            totalMax += usage.getMax();
        }
        sb.append(new Formatter().format(
            "used: %.2fMB, reserved: %.2fMB, max: %.2fMB",
            totalUsed / MB, totalReserved / MB, totalMax / MB));

        return sb.toString();
    }

    public static void main(String[] args) throws IOException
    {
        TestIO test = new TestIO();
        test.testOpenFile(args[0]);
    }
}

Br,
Rob

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to [email protected]
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to