let () =
let ob = Buffer.create 2096 in
let oc = open_out "test-file" in
let seq =
Seq.unfold
(fun b ->
if b < 100 * 100 * 100 * 100 then Some (b, b + 1) else None)
0
in
let () =
Seq.iter
(fun _v ->
Buffer.add_string ob ("output");
Buffer.output_buffer oc ob;
Buffer.clear ob)
seq
in
close_out oc
if I compile it directly, memory output never grows over some MBs. Compiled with js_of_ocaml on the other hand let’s the memory consumption grow unbounded.
I’m not sure if this a bug in js_of_ocaml or if I need to do something different?
I’m not familiar with some of the APIs used but one thing which jumps to mind is that while you do Buffer.clear ob, I don’t see an equivalent “flush” for oc. Could it be accumulating in memory in the JSOO version until close_out oc? In other words, are you sure that the buffer is what’s eating up the memory, and not the output channel?
I don’t see anything obvious in https://github.com/ocsigen/js_of_ocaml/tree/master/runtime to explain it. Maybe it accumulates on the JS engine’s side and not in JSOO per se. I didn’t even know we could write files in JavaScript…
In fact, I think the behavior is clear from the jsoo runtime @VPhantom linked to:
See the last conditional test: this function only flushes the internal channel buffer on newlines. If you print large strings without any newline, it will keep growing the internal buffer without limit.
This is different from the behavior of the upstream runtime (in C), which flushes the buffer as soon as it doesn’t have enough space for the incoming input.