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

GC Compaction is only partial #5842

Closed
vicuna opened this issue Dec 4, 2012 · 2 comments
Closed

GC Compaction is only partial #5842

vicuna opened this issue Dec 4, 2012 · 2 comments

Comments

@vicuna
Copy link

vicuna commented Dec 4, 2012

Original bug ID: 5842
Reporter: markghayden
Assigned to: @alainfrisch
Status: closed (set by @xavierleroy on 2015-12-11T18:18:23Z)
Resolution: not a bug
Priority: high
Severity: major
Version: 4.00.1
Category: runtime system and C interface

Bug description

When I call Gc.compact do not appear to release all unused spaced on the heap. Our software does make use of weak references and finalizers. It uses a large number of 3rd party libraries and external C code. Calling Gc.full_major and/or Gc.compact multiple times does not seem to affect the situation significantly. This appears to happen reliably in my app.

My Ocaml software (www.seaiq.com) runs on devices (Apple iPads and iPhones) with limited memory and often receives memory warnings from the operating system. In such situations, a failure to release sufficient memory can cause the app to be killed. The fact that compaction appears to only release part of the free memory and often leaves as much or more free memory chunks as live memory is quite problematic.

Are there known situations where free space is not released as part of a compaction? Please let me know if I'm misinterpreting the purpose of Gc.compact or if there is something else my app needs to do in order to actually release all free memory.

Thanks!

Steps to reproduce

This happens reliably in my app. I don't have a small test program at this point. I'd like to know this is not a known issue or expected behavior before spending the time to generate one.

Additional information

Dec 4 10:19:32 unknown SEAiq[4570] : PLOTTER_GEN:memory_warning:begin
Dec 4 10:19:32 unknown SEAiq[4570] : minor_words=98085359
Dec 4 10:19:32 unknown SEAiq[4570] : promoted_words=4635560
Dec 4 10:19:32 unknown SEAiq[4570] : major_words=20002328
Dec 4 10:19:32 unknown SEAiq[4570] : minor_collections=418
Dec 4 10:19:32 unknown SEAiq[4570] : major_collections=33
Dec 4 10:19:32 unknown SEAiq[4570] : heap_words=4527104
Dec 4 10:19:32 unknown SEAiq[4570] : heap_chunks=28
Dec 4 10:19:32 unknown SEAiq[4570] : live_words=4041179
Dec 4 10:19:32 unknown SEAiq[4570] : live_blocks=563299
Dec 4 10:19:32 unknown SEAiq[4570] : free_words=485914
Dec 4 10:19:32 unknown SEAiq[4570] : free_blocks=24829
Dec 4 10:19:32 unknown SEAiq[4570] : largest_free=61444
Dec 4 10:19:32 unknown SEAiq[4570] : fragments=11
Dec 4 10:19:32 unknown SEAiq[4570] : compactions=7
Dec 4 10:19:32 unknown SEAiq[4570] : top_heap_words=7720960
Dec 4 10:19:32 unknown SEAiq[4570] : PLOTTER_GEN:compacting:begin
Dec 4 10:19:32 unknown SEAiq[4570] : PLOTTER_GEN:compacting:end
Dec 4 10:19:32 unknown SEAiq[4570] : minor_words=98093975
Dec 4 10:19:32 unknown SEAiq[4570] : promoted_words=4635560
Dec 4 10:19:32 unknown SEAiq[4570] : major_words=20002781
Dec 4 10:19:32 unknown SEAiq[4570] : minor_collections=418
Dec 4 10:19:32 unknown SEAiq[4570] : major_collections=35
Dec 4 10:19:32 unknown SEAiq[4570] : heap_words=1142784
Dec 4 10:19:32 unknown SEAiq[4570] : heap_chunks=9
Dec 4 10:19:32 unknown SEAiq[4570] : live_words=611600
Dec 4 10:19:32 unknown SEAiq[4570] : live_blocks=85487
Dec 4 10:19:32 unknown SEAiq[4570] : free_words=531182
Dec 4 10:19:32 unknown SEAiq[4570] : free_blocks=6
Dec 4 10:19:32 unknown SEAiq[4570] : largest_free=126976
Dec 4 10:19:32 unknown SEAiq[4570] : fragments=2
Dec 4 10:19:32 unknown SEAiq[4570] : compactions=8
Dec 4 10:19:32 unknown SEAiq[4570] : top_heap_words=7720960
Dec 4 10:19:32 unknown SEAiq[4570] : PLOTTER_GEN:memory_warning:end

@vicuna
Copy link
Author

vicuna commented Dec 4, 2012

Comment author: @damiendoligez

Unless you have changed the space_overhead setting from its default value of 80, the GC (including the compactor) tries to maintain the heap_words/live_words ratio at 1.8 (= 1 + space_overhead/100).
In your sample, the ratio is 1.87, pretty close to the target.

You can set space_overhead lower, but this is a space/time trade-off: the lower the overhead, the more time you will spend in the GC.

@vicuna
Copy link
Author

vicuna commented Dec 5, 2012

Comment author: markghayden

Thanks for the explanation. When I use the following code, I get the desired results (almost all free memory is released). It might help to clarify the behavior in the documentation for the function.

From my perspective this is resolved.

thanks! Mark

let do_gc_compact () =
let control = Gc.get () in
let overhead = control.Gc.space_overhead in
control.Gc.space_overhead <- 1 ;
Gc.set control ;
Gc.compact () ;
control.Gc.space_overhead <- overhead ;
Gc.set control ;
;;

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