Skip to content

Flambda creates spurious roots #9978

@jhjourdan

Description

@jhjourdan

Consider the following program:

let root = ref [||]
let free () = root := [||]; Gc.full_major ()
let () =
  root := Array.make 100000000 0;
  free ();
  root := Array.make 100000000 0;
  free ();
  root := Array.make 100000000 0;
  free ();
  root := Array.make 100000000 0;
  free ();
  root := Array.make 100000000 0;
  free ();
  root := Array.make 100000000 0;
  free ();
  root := Array.make 100000000 0;
  free ();
  root := Array.make 100000000 0;
  free ();
  root := Array.make 100000000 0;
  free ();
  root := Array.make 100000000 0;
  free ();
  root := Array.make 100000000 0;
  free ();
  root := Array.make 100000000 0;
  free ();
  root := Array.make 100000000 0;
  free ();
  root := Array.make 100000000 0;
  free ();
  root := Array.make 100000000 0;
  free ();
  root := Array.make 100000000 0;
  free ()

In trunk, and when flambda is enabled, the heap is grown up to several gigabytes, but stays under 1GB when flambda is disabled.
The issue exists both with the default optimzation level of flambda and with -O3.

The reason is that flambda creates spurious global roots each time Array.make is called, so that the corresponding arrays are never reclaimed by the GC. These roots are called camlTest__Pccall_xxx, where xxx is an integer.

Not only this is a memory leak, but I would argue that this is also a performance regression, since it seems like there is a write and a read to this spurious root each time a C function is called. These memory accesses seem purely useless and should be removed.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions