Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Modules can leak memory #5932

Closed
vicuna opened this issue Feb 25, 2013 · 1 comment
Closed

Modules can leak memory #5932

vicuna opened this issue Feb 25, 2013 · 1 comment

Comments

@vicuna
Copy link

vicuna commented Feb 25, 2013

Original bug ID: 5932
Reporter: @mmottl
Assigned to: @alainfrisch
Status: closed (set by @xavierleroy on 2015-12-11T18:18:32Z)
Resolution: duplicate
Priority: normal
Severity: major
Version: 4.00.1
Category: back end (clambda to assembly)
Duplicate of: #5098
Monitored by: @ygrek @mmottl

Bug description

Though this issue is particularly important with first-class modules, because they are much more frequently allocated and may stay around for a long time, this seems to be a general issue with module code. Here is an example where first-class modules leak memory:


module type S = sig val x : int end

module type T = sig
include S (* swap )
val y : string (
swap *)
end

let copy (module M : T) = (module M : S)

let alloc () =
copy (module struct
let x = 42
let y = String.create 100_000_000
end : T)

let main () =
let m = alloc () in
Gc.full_major ();
Gc.print_stat stdout;
m

let () = ignore (main ())

The GC stats (live words) printed by this example show that even after a full major collection the string "y" in an allocated module stays around after the signature of the module has been constrained to not contain "y" in a presumed copy of the original module. If you swap the two lines marked by the comment "swap" in the above code, the problem goes away, because the compiler is forced to reallocate the constrained module due to a different memory layout and can hence "forget" "y".

The assembly code shows that in the first (buggy) case the compiler merely returns the pointer to the original module in the "copy" function. That's sound in the sense that there will not be a segfault if the target signature is a "prefix" of the source signature. But this will, of course, leak memory. The compiler will correctly allocate a fresh, "smaller" module if the target signature is not a "prefix" of the source.

One could argue that this behavior may be acceptable with file modules, because they have a more "static" feel. But I don't think this is acceptable with first-class or even local modules. Values that have been "constrained away" should not only be inaccessible, they should also be reclaimed by the GC.

@vicuna
Copy link
Author

vicuna commented Feb 25, 2013

Comment author: @alainfrisch

Closing, as this is a duplicate of #5098.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants