Re: lablgtk missing macros to live in harmony with the garbage collector

Claude Marché <[email protected]> Tue, 27 Jan 2015 22:23:13 +0100
Newsgroups gmane.comp.lang.ocaml.lib.gtk
Message-ID <[email protected]>
This is a multi-part message in MIME format.
--------------010004000609050509050201
Content-Type: multipart/alternative;
 boundary="------------000203060503090001030604"


--------------000203060503090001030604
Content-Type: text/plain; charset=windows-1252
Content-Transfer-Encoding: quoted-printable

Hi,

I'm not sure if it is related to your problem, but it may: in the past,
within the lablgtk interface of Why3, we also noticed
an excessive use of memory. My colleague Guillaume Melquiond discovered
an issue with the GC. A successful work-around was to
call, before each GTK operation (typically at the beginning of each
callbacks, at least the mostly used ones) the function

external reset_gc : unit -> unit =3D "ml_reset_gc"

where ml_reset_gc is defined in the attached file

The difference was impressive! Part of the explanation is given in the
attached file, and also in this comment that I copy/paste:

external reset_gc : unit -> unit =3D "ml_reset_gc"
(* Setting a Gc.alarm is pointless; the function has to be called manuall=
y
   before each lablgtk operation. Indeed, each major slice resets
   caml_extra_heap_resources to zero, but alarms are executed only at
   finalization time, that is, after a full collection completes. Note th=
at
   manual calls can fail to prevent extraneous collections too, if a majo=
r
   slice happens right in the middle of a sequence of lablgtk operations =
due
   to memory starvation. Hopefully, it seldom happens. *)
let () =3D reset_gc ()

Hope this helps. Any comment/suggestion is welcome.

- Claude

On 01/27/2015 07:52 PM, Felix Ruess wrote:
> Hi guys,
>
> I noticed that our applications seem to use more and more memory the
> longer they run.
> Profiling it, it looks like most of it is coming from closures that
> use GObj and GtkSignal.
>
> It looks like most parts of lablgtk don't properly use the CAMLparam,
> CAMLreturn, etc macros that are described here:
> http://caml.inria.fr/pub/docs/manual-ocaml/intfc.html#sec440
> Fixing a similar issue in some of our code interfacing with C made a
> HUGE difference.
>
> E.g. the ml_g_signal_override_class_closure function in ml_gobject.c
> does not use these macros...
> Any particular reason for that? Am I missing something here, or is
> that a bug (or rather lots of bugs)?
>
> Cheers, Felix
>
>
> _______________________________________________
> Lablgtk-list mailing list
> [email protected]
> https://lists.ocamlcore.org/cgi-bin/listinfo/lablgtk-list


--=20
Claude March=E9                          | tel: +33 1 72 92 59 69
INRIA Saclay - =CEle-de-France           |
Universit=E9 Paris-sud, Bat. 650         | http://www.lri.fr/~marche/
F-91405 ORSAY Cedex                    |


--------------000203060503090001030604
Content-Type: text/html; charset=windows-1252
Content-Transfer-Encoding: quoted-printable

<html>
  <head>
    <meta content=3D"text/html; charset=3Dwindows-1252"
      http-equiv=3D"Content-Type">
  </head>
  <body text=3D"#000000" bgcolor=3D"#FFFFFF">
    <div class=3D"moz-cite-prefix">Hi,<br>
      <br>
      I'm not sure if it is related to your problem, but it may: in the
      past, within the lablgtk interface of Why3, we also noticed<br>
      an excessive use of memory. My colleague Guillaume Melquiond
      discovered an issue with the GC. A successful work-around was to<br=
>
      call, before each GTK operation (typically at the beginning of
      each callbacks, at least the mostly used ones) the function<br>
      <br>
      external reset_gc : unit -&gt; unit =3D "ml_reset_gc"<br>
      <br>
      where ml_reset_gc is defined in the attached file<br>
      <br>
      The difference was impressive! Part of the explanation is given in
      the attached file, and also in this comment that I copy/paste:<br>
      <br>
      external reset_gc : unit -&gt; unit =3D "ml_reset_gc"<br>
      (* Setting a Gc.alarm is pointless; the function has to be called
      manually<br>
      =A0=A0 before each lablgtk operation. Indeed, each major slice rese=
ts<br>
      =A0=A0 caml_extra_heap_resources to zero, but alarms are executed o=
nly
      at<br>
      =A0=A0 finalization time, that is, after a full collection complete=
s.
      Note that<br>
      =A0=A0 manual calls can fail to prevent extraneous collections too,=
 if
      a major<br>
      =A0=A0 slice happens right in the middle of a sequence of lablgtk
      operations due<br>
      =A0=A0 to memory starvation. Hopefully, it seldom happens. *)<br>
      let () =3D reset_gc ()<br>
      <br>
      Hope this helps. Any comment/suggestion is welcome.<br>
      <br>
      - Claude<br>
      <br>
      On 01/27/2015 07:52 PM, Felix Ruess wrote:<br>
    </div>
    <blockquote
cite=3D"mid:[email protected]=
ail.com"
      type=3D"cite">
      <div dir=3D"ltr">
        <div>
          <div>
            <div>
              <div>
                <div>
                  <div>
                    <div>Hi guys,<br>
                      <br>
                    </div>
                    I noticed that our applications seem to use more and
                    more memory the longer they run.<br>
                  </div>
                  Profiling it, it looks like most of it is coming from
                  closures that use GObj and GtkSignal.<br>
                  <br>
                </div>
                It looks like most parts of lablgtk don't properly use
                the CAMLparam, CAMLreturn, etc macros that are described
                here: <a moz-do-not-send=3D"true"
                  href=3D"http://caml.inria.fr/pub/docs/manual-ocaml/intf=
c.html#sec440">http://caml.inria.fr/pub/docs/manual-ocaml/intfc.html#sec4=
40</a><br>
              </div>
              Fixing a similar issue in some of our code interfacing
              with C made a HUGE difference.<br>
              <br>
            </div>
            E.g. the ml_g_signal_override_class_closure function in
            ml_gobject.c does not use these macros...<br>
          </div>
          Any particular reason for that? Am I missing something here,
          or is that a bug (or rather lots of bugs)?<br>
          <br>
        </div>
        Cheers, Felix<br>
      </div>
      <br>
      <fieldset class=3D"mimeAttachmentHeader"></fieldset>
      <br>
      <pre wrap=3D"">_______________________________________________
Lablgtk-list mailing list
<a class=3D"moz-txt-link-abbreviated" href=3D"mailto:[email protected]=
orge.ocamlcore.org">[email protected]</a>
<a class=3D"moz-txt-link-freetext" href=3D"https://lists.ocamlcore.org/cg=
i-bin/listinfo/lablgtk-list">https://lists.ocamlcore.org/cgi-bin/listinfo=
/lablgtk-list</a>
</pre>
    </blockquote>
    <br>
    <br>
    <pre class=3D"moz-signature" cols=3D"72">--=20
Claude March=E9                          | tel: +33 1 72 92 59 69
INRIA Saclay - =CEle-de-France           |
Universit=E9 Paris-sud, Bat. 650         | <a class=3D"moz-txt-link-freet=
ext" href=3D"http://www.lri.fr/~marche/">http://www.lri.fr/~marche/</a>
F-91405 ORSAY Cedex                    |
</pre>
  </body>
</html>

--------------000203060503090001030604--

--------------010004000609050509050201
Content-Type: text/x-csrc;
 name="resetgc.c"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
 filename="resetgc.c"

#include <caml/mlvalues.h>
#include <caml/memory.h>

/* Whenever this variable reaches 1, a garbage collection starts and the
   variable is reset to 0. Unfortunately, it might take as few as 50
   allocations of Glib/Gdk/Gtk objects for the variable to go from 0 to 1.
   Most IDE operations involve tens, if not, hundreds, of such objects,
   thus causing the garbage collector to constantly run. */
extern double caml_extra_heap_resources;

/* Set the accumulator to -inf to prevent it from reaching 1. It might
   still reach it, since any collection sets it to 0, so the hack only
   works for a short while. */
CAMLprim value ml_reset_gc(value unit)
{
  CAMLparam1(unit);
  caml_extra_heap_resources = - 1.0 / 0.0;
  CAMLreturn(Val_unit);
}

--------------010004000609050509050201
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

_______________________________________________
Lablgtk-list mailing list
[email protected]
https://lists.ocamlcore.org/cgi-bin/listinfo/lablgtk-list

--------------010004000609050509050201--