On 04/01/2012, Damien Doligez <[email protected]> wrote:
> On 2012-01-01, at 13:44, Richard W.M. Jones wrote:
>
>> Is compaction disabled?  lablgtk disables it unconditionally by
>> setting the global Gc max_overhead (see also the Gc documentation):
>>
>>  src/gtkMain.ml:
>>    let () = Gc.set {(Gc.get()) with Gc.max_overhead = 1000000}
>
> Anyone who disables compaction should seriously consider switching
> to the first-fit allocation policy:
>
>   let () = Gc.set {(Gc.get ()) with Gc.allocation_policy = 1}
>
> This may slow down allocations a bit, but the theory tells us that
> it completely prevents unbounded fragmentation of the OCaml heap.

I've often wondered what I should do when using lablgtk. It's a pretty
annoying issue and, as far as I understand, OCaml will only return the
memory to the OS upon compactions.

There is however something to do. Quoting lablgtk's README:
> IMPORTANT: Some Gtk data structures are allocated in the Caml heap,
> and their use in signals (Gtk functions internally cally callbacks)
> relies on their address being stable during a function call. For
> this reason automatic compation is disabled in GtkMain. If you need
> it, you may use compaction through Gc.compact where it is safe
> (timeouts, other threads...), but do not enable automatic compaction.

I've never really understood why it worked: I'm surprised the GC would
update addresses stored in the C side of GTK.

If you want to use timeouts, the following should work:
  Glib.Timeout.add ~ms:0 ~callback:(fun () -> Gc.compact (); false)

I guess that Glib.Idle.add would work too.

That guarantees nothing about the time the compaction will run however
and in practice, adding a timeout or an idle and starting a long-running
and uninterruptible computation right after will severely delay the
compaction.

I haven't had the time to try it but it should be possible to pump
glib's event loop by hand in order to trigger the compaction. Another
possibility would be to spawn a thread and use a mutex to wait until the
compaction is done. And in case you're using Lwt, well, I don't know but
I'd expect the callback to be callable whenever threads can be switched.

Maybe that if it were possible to have a callback called each time the
runtime would like to do a compaction, this could be automated.

Regards,
Adrien Nader

-- 
Caml-list mailing list.  Subscription management and archives:
https://sympa-roc.inria.fr/wws/info/caml-list
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
Bug reports: http://caml.inria.fr/bin/caml-bugs

Reply via email to