Re: [Caml-list] Re: memory usage

2009-01-13 Thread John Lepikhin

 Yeah, I flushed the output and I used /dev/zero - I still see no
 messages.

That's strange. Anyway, it looks like a memory leak, isn't it?

20 threads * 1KB max = 20 KB of memory for data storage should be used
(plus 20KB*500% for heap overhead = 100KB). I changed delay to 1 ms:

ignore (Unix.select [] [] [] 0.001);

After 2 minutes of work on FreeBSD, 19MB(!) was used:

# ps auxw | grep a.out | grep -v grep
root 35136 30.1  0.2 60348 19304  p5  L+1:36PM   2:08.07 ./a.out

# pmap PID:

Address  Kbytes  RSS Shared Priv Mode  Mapped File
0040204  360  -  360 r-x   /tmp/a.out
00532000 80   76  -   80 rw-   /tmp/a.out
00546000 28   16  -   28 rw- [ anon ]
40532000148  108148- r-x   /libexec/ld-elf.so.1
40557000132  108  -  132 rw- [ anon ]
40657000 28   28  -   28 rw-   /libexec/ld-elf.so.1
4065E000 24   20  -   24 rw- [ anon ]
40664000 92   76 92- r-x   /lib/libm.so.5
4067B000  44  -4 r-x   /lib/libm.so.5
4067C000   10240   1024- r-x   /lib/libm.so.5
4077C000  88  -8 rw-   /lib/libm.so.5
4077E000 64   64 64- r-x   /lib/libthr.so.3
4078E000  44  -4 r-x   /lib/libthr.so.3
4078F000   1024   12   1024- r-x   /lib/libthr.so.3
4088F000 12   12  -   12 rw-   /lib/libthr.so.3
40892000  88  -8 rw- [ anon ]
40894000932  452932- r-x   /lib/libc.so.7
4097D000  44  -4 r-x   /lib/libc.so.7
4097E000   10200   1020- r-x   /lib/libc.so.7
40A7D000116  116  -  116 rw-   /lib/libc.so.7
40A9A000 92   36  -   92 rw- [ anon ]
40B0  44032  13976- 44032 rw- [ anon ]
785A4000128   12  -  128 rw- [ anon ]
787A5000128   12  -  128 rw- [ anon ]
789A6000128   12  -  128 rw- [ anon ]
78BA7000128   12  -  128 rw- [ anon ]
78DA8000128   12  -  128 rw- [ anon ]
78FA9000128   12  -  128 rw- [ anon ]
...

(gdb) info thr
  18 Thread 0x40b01120 (LWP 101068)  0x408e4d4c in _umtx_op ()
from /lib/libc.so.7
  17 Thread 0x40b01290 (LWP 100489)  0x40971cfc in select ()
from /lib/libc.so.7
  16 Thread 0x40b01b30 (LWP 100079)  0x408e4d4c in _umtx_op ()
from /lib/libc.so.7
  15 Thread 0x40b04d80 (LWP 100858)  0x40971cfc in select ()
from /lib/libc.so.7
  14 Thread 0x40b02260 (LWP 101096)  0x408e4d4c in _umtx_op ()
from /lib/libc.so.7
  13 Thread 0x40b04200 (LWP 101128)  0x40971cfc in select ()
from /lib/libc.so.7
  12 Thread 0x40b03960 (LWP 101175)  0x408e4d4c in _umtx_op ()
from /lib/libc.so.7
  11 Thread 0x40b02820 (LWP 101189)  0x408e4d4c in _umtx_op ()
from /lib/libc.so.7
  10 Thread 0x40b03680 (LWP 101217)  0x408e4d4c in _umtx_op ()
from /lib/libc.so.7
  9 Thread 0x40b03f20 (LWP 100057)  0x408e4d4c in _umtx_op ()
from /lib/libc.so.7
  8 Thread 0x40b020f0 (LWP 100066)  0x40971cfc in select ()
from /lib/libc.so.7
  7 Thread 0x40b05ec0 (LWP 100535)  0x40971cfc in select ()
from /lib/libc.so.7
  6 Thread 0x40b04370 (LWP 100564)  0x408e4d4c in _umtx_op ()
from /lib/libc.so.7
  5 Thread 0x40b04c10 (LWP 100698)  0x40971cfc in select ()
from /lib/libc.so.7
  4 Thread 0x40b02b00 (LWP 101224)  0x40971cfc in select ()
from /lib/libc.so.7
  3 Thread 0x40b03ad0 (LWP 101227)  0x40971cfc in select ()
from /lib/libc.so.7
  2 Thread 0x40b037f0 (LWP 101258)  0x408e4d4c in _umtx_op ()
from /lib/libc.so.7
* 1 Thread 0x40b05620 (LWP 100101)  0x409643dc in open ()
from /lib/libc.so.7
(gdb) 

I also added special thread to check GC:

let print_stats _ =
  while true do
Gc.compact ();
Gc.print_stat stdout;
flush stdout;
Unix.sleep 10;
  done

Thread.create print_stats ();

GC statistics after 1 minute:

minor_words: 21929847-- ?
promoted_words: 2474840
major_words: 2939105
minor_collections: 1655
major_collections: 635
heap_words: 61440
heap_chunks: 1
top_heap_words: 61440
live_words: 1024
live_blocks: 115
free_words: 60416
free_blocks: 1
largest_free: 60416
fragments: 0
compactions: 7


___
Caml-list mailing list. Subscription management:
http://yquem.inria.fr/cgi-bin/mailman/listinfo/caml-list
Archives: http://caml.inria.fr
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
Bug reports: http://caml.inria.fr/bin/caml-bugs


[Caml-list] Re: memory usage

2009-01-12 Thread Sylvain Le Gall
On 12-01-2009, John Lepikhin j...@ispsystem.com wrote:
 Starting point should be to call this periodically:
 
   Gc.compact ();
   let stat = Gc.stat () in
   let live_words = stat.Gc.live_words in
   eprintf live words %d\n%! live_words;
 
 which will tell you how many words (ie 4 or 8 byte chunks) are
 reachable according to the garbage collector.

 Richard, here is result (statistics was saved every 10 seconds):

 live words - RSS:

 186980 - 12380KB -- after first 10 seconds of work
 154156 - 18232KB
 153923 - 19648KB
 ...
 after 10 minutes of work:
 203842 - 33436KB
 170559 - 33528KB
 187018 - 33664KB
 71626 - 33592KB

 Sometimes live words drops down to 40.000. But RSS always stay near
 30-50MB.


To get real memory used, (Sys.word_size * live_word / 8). Do you use
out-of-heap datastructure that can use memory ? (malloc-ed
datastructure).

Regards,
Sylvain Le Gall

___
Caml-list mailing list. Subscription management:
http://yquem.inria.fr/cgi-bin/mailman/listinfo/caml-list
Archives: http://caml.inria.fr
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
Bug reports: http://caml.inria.fr/bin/caml-bugs


Re: [Caml-list] Re: memory usage

2009-01-12 Thread John Lepikhin

  The only specific module is ocaml-fd (send file descriptors over pipes).
 What version of OCaml is this?

3.10.2.

 I'm afraid to say that you'll have to post a short reproducer here
 before I can look at this further ...

Yes, it could be the simplest solution. I have this issue only under the
high load, on production server, with real client applications. At this
time, I have no idea how to reduce code from big commercial application
to something short. May be I'll create some stand-alone GC test later.

P.S. Interesting thing I found on other machine, where application works
with another load: after the same number of connections processed, only
5MB was allocated (feel the difference: 5MB and 40MB, both after
processing 250.000 connections). The only difference is the first
machine had processed 250.000 connections in 5 hours (up to ~20
concurrent threads), the second in 24 hours (up to ~10 concurrent
threads).

___
Caml-list mailing list. Subscription management:
http://yquem.inria.fr/cgi-bin/mailman/listinfo/caml-list
Archives: http://caml.inria.fr
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
Bug reports: http://caml.inria.fr/bin/caml-bugs


[Caml-list] Re: memory usage

2009-01-12 Thread Sylvain Le Gall
On 12-01-2009, John Lepikhin j...@ispsystem.com wrote:

  Each thread is killed after work is done
 How do you kill the threads? I hope this is just a figure of
 speech for I do an orderly shutdown of each thread after work is done.

 Well, that was consequence of my bad English :-) Threads finish their
 work and exit. I also made a simple wrapper to Thread.create to be sure
 that all work inside threads is done:

 module MyThread =
   let create f p =
 let dowork _ =
   (* log thread creation *)
   f p;
   (* log thread shutdown *)
 in
 Thread.create dowork ()
 end

Do you use some kind of Thread.join ? 

Regards
Sylvain Le Gall

___
Caml-list mailing list. Subscription management:
http://yquem.inria.fr/cgi-bin/mailman/listinfo/caml-list
Archives: http://caml.inria.fr
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
Bug reports: http://caml.inria.fr/bin/caml-bugs


Re: [Caml-list] Re: memory usage

2009-01-12 Thread John Lepikhin
 I'm afraid to say that you'll have to post a short reproducer here
 before I can look at this further ...

I'm not sure this is the same issue. Look at this test code:


let threads_counter = ref 0

let counter_mutex = Mutex.create ()

let send_data data size =
let fd = Unix.openfile /dev/null [ Unix.O_WRONLY ] 0o644 in
ignore (Unix.write fd data 0 size);
Unix.close fd

let read_data _ =
let fd = Unix.openfile /dev/random [] 0o644 in
let buffer = String.create 1024 in
let br = Unix.read fd buffer 0 (Random.int 1000) in
Unix.close fd;
ignore (Unix.select [] [] [] 0.1);
send_data buffer br

let do_work _ =
read_data ();

Mutex.lock counter_mutex;
decr threads_counter;
Mutex.unlock counter_mutex

let _ =
while true do
Mutex.lock counter_mutex;
if !threads_counter  20 then
begin
incr threads_counter;

ignore (Thread.create do_work ());
end;
Mutex.unlock counter_mutex;
done;
Unix.sleep 100


It checks if thread count is less than 20. If so, new thread is created
and threads_counter incremented. After thread is done, threads_counter
is decremented.

After 5 minutes of work, RSS usage was grown from 3300KB to 5670KB on
FreeBSD 7.0 and from 976KB to 1200KB on Linux. In both cases Ocaml
3.10.2 was used.

___
Caml-list mailing list. Subscription management:
http://yquem.inria.fr/cgi-bin/mailman/listinfo/caml-list
Archives: http://caml.inria.fr
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
Bug reports: http://caml.inria.fr/bin/caml-bugs


[Caml-list] Re: memory usage

2009-01-12 Thread Sylvain Le Gall
Can you make sure that all your function terminate and are joined
(Thread.join). I think this will help to make sure that the thread exit
and call thread_kill (see OCaml source code).

If you take a look at thread_kill there is a function stat_free + set to
NULL things called stack_low, stack_high... Maybe all the data you are
seeing come from this...

I am not sure that Thread.join will free anything, but it will help you
to be sure that your thread has exited correctly.

Regards,
Sylvain Le Gall

___
Caml-list mailing list. Subscription management:
http://yquem.inria.fr/cgi-bin/mailman/listinfo/caml-list
Archives: http://caml.inria.fr
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
Bug reports: http://caml.inria.fr/bin/caml-bugs


Re: [Caml-list] Re: memory usage

2009-01-12 Thread Richard Jones
On Mon, Jan 12, 2009 at 11:03:10PM +0800, John Lepikhin wrote:
 
   The only specific module is ocaml-fd (send file descriptors over pipes).
  What version of OCaml is this?
 
 3.10.2.

Low level parts of the GC were rewritten in 3.11.  Well, the way that
it gets blocks of memory off the operating system anyhow ...

https://bugzilla.redhat.com/show_bug.cgi?id=445545#c9
http://caml.inria.fr/pub/ml-archives/caml-list/2008/05/9c24581520a98afa2e11185845b5458a.en.html

So maybe upgrading to 3.11 is an option for you?  I don't know whether
it will make a difference, but it's possible it will change the
behaviour and 3.11 is quite stable so it's unlikely to introduce any
regressions.

Rich.

-- 
Richard Jones
Red Hat

___
Caml-list mailing list. Subscription management:
http://yquem.inria.fr/cgi-bin/mailman/listinfo/caml-list
Archives: http://caml.inria.fr
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
Bug reports: http://caml.inria.fr/bin/caml-bugs