Mantis Bug Tracker

View Issue Details Jump to Notes ] Issue History ] Print ]
IDProjectCategoryView StatusDate SubmittedLast Update
0006294OCamlruntime system and C interfacepublic2014-01-13 14:012018-11-12 11:22
Assigned Togarrigue 
PlatformOSOS Version
Product Version4.01.0 
Target VersionlaterFixed in Version4.08.0+dev 
Summary0006294: Poor tracking of extra heap resources
DescriptionCurrently, when a custom block is allocated, the caller passes an arbitrary ratio between 0 and 1. This ratio is added to the caml_extra_heap_resources accumulator. Each time the accumulator reaches 1, a garbage collection is triggered and the accumulator is reset to 0.

This "feature" is breaking the usability of Why3ide badly. Consider the following numbers obtained by launching Why3ide on a large testcase.

946.39user 0.36system 16:13.65elapsed 97%CPU (0avgtext+0avgdata 658164maxresident)k
minor_collections: 113838
major_collections: 1424

As you can, it takes mote than 16 minutes before the user can interact with the program. Most of the time is wasted in the garbage collector. If we disable the accumulator, we get the following numbers:

18.98user 0.41system 1:26.67elapsed 22%CPU (0avgtext+0avgdata 761232maxresident)k
minor_collections: 8825
major_collections: 26

Now it takes only 19 seconds for the program to start. That is a x50 speedup!

By the way, this might seem like a degenerate case. But even on smaller testcases, the speedup is noticeable by the user, since each user interaction was triggering a major collection before.

The blame is not solely on OCaml. My opinion is that this is misfeature of OCaml that is misused by Lablgtk, leading to a disastrous user experience when using Labgtk-based applications.

Follow this link if you want to see how we disabled this part of the GC without having to ask our users to recompile OCaml:;a=commitdiff;h=2dbd9e653925b3991b99b0b10ba320b7850ae106 [^]
TagsNo tags attached.
Attached Files

- Relationships
related to 0006133acknowledged Wish: make max size of custom space runtime-configurable 
related to 0004108assigneddoligez Memory-mapping of bigarrays may exhaust address space 
related to 0007676resolveddoligez Allocating custom blocks become expensive with large major heaps 

-  Notes
garrigue (manager)
2014-01-15 14:56

This is a very interesting test case.
I had already noticed slow behavior when using lablgtk from the top-level, but not in standalone applications.

I agree that this is a bad situation, but what you are doing is just disabling the feature.
This is going to work if your program triggers the GC by itself (i.e. if it allocates sufficiently in the heap), but not if it is doing only user interaction without allocating (or allocating very little).
We do not want to run out of extra-heap resources in that case.

I think we need a new approach, but I'm not sure what.
One possibility would be not to trigger the GC when the accumulator reaches 1, but rather to wait some amount of time before doing it (if it doesn't happen before). This would reduce the significance of the fraction, which is almost impossible to choose correctly.
gmelquiond (reporter)
2014-01-15 17:15

I don't think the GC needs to do anything about it. As you say, the fraction is impossible to choose correctly, which makes the mechanism kind of pointless. If the GC needs to be run regularly, it doesn't have to be up to the GC to do it, it might just as well be done by the user program (especially if it is an interactive one).

Ideally, there should be a way to tell the actual footprint of each custom block and the threshold at which point a collection should start. (I thought that was already possible; I must have been mistaken.) Note that this can be accurately emulated in the user space thanks to a global accumulator and some finalizer functions. I guess it would be cheaper in the GC though, since no finalizer would be needed then.
ygrek (reporter)
2014-01-16 03:37

> Ideally, there should be a way to tell the actual footprint of each custom block and the threshold at which point a collection should start.

Probably per resource type?
On a side note, bindings should provide the way to explicitely destroy the expensive resources..
doligez (administrator)
2014-07-11 13:17

> Ideally, there should be a way to tell the actual footprint of each custom block and the threshold at which point a collection should start.

That won't work in the case where all the custom blocks are still alive and the total foot print is still above the threshold after the collection.
gerd (reporter)
2015-09-13 16:38

What about a modification that works similar to way heap memory is managed: we keep track of the footprint of the custom blocks, and aggregate that to alive_custom and total_custom, and a GC is triggered when alive_custom drops below a percentage of total_custom. The percentage is configurable.

With some more thoughts this could maybe even be integrated into the normal GC trigger condition (i.e. GC is triggered when alive_heap+alive_custom gets relatively too low).

I don't see big impl problems. The only thing is that we need a place for storing the footprint of the external part with the custom block (maybe at the end of the heap block, to keep compatibility).
garrigue (manager)
2016-03-06 16:21

For lablgtk2, I've just added a function that allows to change the impact of custom allocation on the GC (including completely ignoring it). In general, I don't know what is the best approach.
frisch (developer)
2018-11-09 14:23

> What about a modification that works similar to way heap memory is managed

Done in [^]

Would be good to get a confirmation that the problem reported here is indeed fixed. Guillaume: if this is still of interest to you, could you try with the current OCaml trunk?
gmelquiond (reporter)
2018-11-09 14:36

It surely is, as we are still shipping our ugly hack in Why3. That said, I am not sure I will experience any improvement by switching to OCaml trunk. If I understand correctly, I would also need a version of Lablgtk that calls the new GC interface, wouldn't I?
doligez (administrator)
2018-11-12 11:22

That's correct. Now that OCaml provides a better API, we will need to change lablgtk to use it.

- Issue History
Date Modified Username Field Change
2014-01-13 14:01 gmelquiond New Issue
2014-01-15 14:56 garrigue Note Added: 0010801
2014-01-15 14:56 garrigue Assigned To => garrigue
2014-01-15 14:56 garrigue Status new => feedback
2014-01-15 17:15 gmelquiond Note Added: 0010802
2014-01-15 17:15 gmelquiond Status feedback => assigned
2014-01-16 03:37 ygrek Note Added: 0010803
2014-01-17 17:50 doligez Relationship added related to 0006133
2014-07-11 13:17 doligez Note Added: 0011800
2014-07-11 13:17 doligez Target Version => 4.02.1+dev
2014-09-04 00:25 doligez Target Version 4.02.1+dev => undecided
2014-09-15 21:57 doligez Target Version undecided => 4.03.0+dev / +beta1
2015-07-25 09:02 xleroy Relationship added related to 0004108
2015-09-13 16:38 gerd Note Added: 0014449
2015-11-27 18:16 frisch Target Version 4.03.0+dev / +beta1 => later
2016-03-06 16:21 garrigue Note Added: 0015442
2017-02-23 16:43 doligez Category OCaml runtime system => runtime system
2017-03-03 17:45 doligez Category runtime system => runtime system and C interface
2017-12-20 18:03 xleroy Relationship added related to 0007676
2018-11-09 14:23 frisch Note Added: 0019441
2018-11-09 14:32 frisch Fixed in Version => 4.08.0+dev
2018-11-09 14:36 gmelquiond Note Added: 0019446
2018-11-12 11:22 doligez Note Added: 0019451

Copyright © 2000 - 2011 MantisBT Group
Powered by Mantis Bugtracker