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

Garbage collection #24

Closed
liquidev opened this issue Mar 19, 2022 · 4 comments
Closed

Garbage collection #24

liquidev opened this issue Mar 19, 2022 · 4 comments

Comments

@liquidev
Copy link
Member

Some things simply cannot be collected when using reference counting, and even though GC is less predictable, that's not really something you worry about in high-level languages such as Mica.

@liquidev liquidev added the VM label Mar 19, 2022
@liquidev liquidev added this to the 0.3.0 milestone Mar 30, 2022
@liquidev
Copy link
Member Author

Turns out GC is way faster than RC, too. Making values not have an explicit Drop implementation prevents a lot of branching that would otherwise occur in a destructor.
(see #55)

> hyperfine --warmup 5 'target/release/mica code/functions.mi' 'target/release/mica-nodestructors code/functions.mi'
Benchmark 1: target/release/mica code/functions.mi
  Time (mean ± σ):     344.4 ms ±   5.1 ms    [User: 342.1 ms, System: 1.9 ms]
  Range (min … max):   338.4 ms … 356.3 ms    10 runs
 
Benchmark 2: target/release/mica-nodestructors code/functions.mi
  Time (mean ± σ):     288.2 ms ±   1.5 ms    [User: 286.8 ms, System: 1.4 ms]
  Range (min … max):   286.6 ms … 291.2 ms    10 runs
 
Summary
  'target/release/mica-nodestructors code/functions.mi' ran
    1.20 ± 0.02 times faster than 'target/release/mica code/functions.mi'

I'm adding this to 0.3.0.

@liquidev
Copy link
Member Author

liquidev commented Apr 1, 2022

The GC should be controllable by the user, using a built-in global Gc. The following methods should be available:

impl Gc
  # Disables automatic garbage collection; collect/0 static must be called to prevent leaks.
  func disable() static

  # Makes the GC run on most allocations. In most cases this is not what you want, as this is only useful for
  # debugging the GC.
  func enable_always_run() static

  # Makes the GC run periodically every time an amount of bytes is allocated.
  # `next_run` then gets updated to `allocated_bytes * growth_factor / 256`.
  # This is the default, with `next_run = 65536` and `growth_factor = 384`.
  func enable_with_ceiling(next_run, growth_factor) static

  # Triggers a garbage collection now.
  func collect() static

  # Returns the amount of bytes currently allocated by the GC.
  func allocated_bytes() static
end

@liquidev
Copy link
Member Author

liquidev commented Apr 3, 2022

I'm a little worried that maybe the GC doesn't fire often enough. Not all allocations are managed by it (foreign allocations in particular are not controlled by the GC). We'll see how it is in practice.

@liquidev
Copy link
Member Author

liquidev commented Apr 3, 2022

I'll call this closed for now; future concerns about the GC's performance or other implementation stuff can be raised in new issues.

@liquidev liquidev closed this as completed Apr 3, 2022
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

1 participant