MMTk is under active development and is not yet ready for production use. However, even at this early stage, GC researchers and VM developers can start exploring it and using it experimentally.
If you are a GC researcher, you can start working with the code base now, although the internal abstractions are subject to change and the mechanisms provided by MMTk may not yet be optimal. (Read the tutorial for more information.)
If you are a language implementer, there should already be enough in place for you to start porting to MMTk. (Read the porting guide for more information.)
Features
Implemented collectors
We have implemented several collectors (called “plan” in MMTk’s terminology). The code for the plans is in the mmtk-core.
- NoGC: It never does any GC. Will panic when the heap memory is exhausted. Similar to the Epsilon GC in OpenJDK. Useful for initial porting.
- MarkSweep: The classic non-moving mark-sweep algorithm. It has a segregated free-list allocator we implemented in Rust using MiMalloc as a reference.
- MarkCompact: A LISP2-style mark-compact algorithm which uses per-object forwarding words.
- Compressor: The Compressor mark-compact algorithm which uses bitmap instead of per-object forwarding words.
- SemiSpace: The classic evacuating semi-space algorithm.
- GenCopy: A generational copying collector. It has an evacuating nursery, and uses the semi-space algorithm for the mature space.
- Immix: A space-efficient high-throughput mark-region collector, with opportunistic
defragmentation. See this paper. It has several variants:
- GenImmix: A generational collector with an evacuating nursery, using Immix for the mature space.
- StickyImmix: A variant of Immix that implements in-place generational GC without an additional evacuating nursery. It uses the mark bit (i.e. the “sticky mark bit”) to identify old objects during nursery GC.
- ConcurrentImmix: An Immix variant that uses non-moving concurrent collection (with concurrent marking and stop-the-world releasing) and falls back to stop-the-world full-heap GC with opportunistic defragmentation. It uses an object-logging snapshot-at-the-beginning (SATB) write barrier.
-
LXR: A concurrent collector based on Immix, having both low latency and high throughput. It uses a combination of reference counting and tracing algorithms. See this paper.
LXR has not been merged into master, yet, but is available in the following repositories:
-
Iso: A request-private garbage collector based on Immix. It performs thread-local concurrent collection, and the current implementation falls back to stop-the-world global collection. See this paper.
Iso has not been merged into master, yet, and requires changes to the OpenJDK runtime. It is available in the following repositories.
The original Java MMTk from which the Rust MMTk has evolved supports a large number of collectors, and we will be incorporating many of those in the near future.
Officially supported bindings
We have several officially supported VM bindings, which are:
- OpenJDK: https://github.com/mmtk/mmtk-openjdk
- JikesRVM (Using the Rust MMTk for GC instead of JikesRVM’s original MMTk): https://github.com/mmtk/mmtk-jikesrvm
- V8: https://github.com/mmtk/mmtk-v8
- Ruby: https://github.com/mmtk/mmtk-ruby
- Julia: https://github.com/mmtk/mmtk-julia
There are other VM bindings developed by third parties, such as GHC, PyPy, Scala/Native, etc.
Feature matrix
Each VM binding supports a subset of collectors (called “plan” in MMTk’s terminology) the MMTk core provides, depending on development progress and VM requirements.
Plan | OpenJDK | JikesRVM | V8 | Ruby | Julia |
---|---|---|---|---|---|
NoGC | Yes | Yes | Yes | Yes | Yes |
MarkSweep | Yes | Yes | No | Yes | Yes |
MarkCompact | Yes | No | No | N/A (pin) | N/A (pin) |
Compressor | Yes | No | No | N/A (pin) | N/A (pin) |
SemiSpace | Yes | Yes | No | N/A (pin) | N/A (pin) |
GenCopy | Yes | No | No | N/A (pin) | N/A (pin) |
Immix | Yes | No | No | Yes | Yes |
GenImmix | Yes | No | No | N/A (pin) | N/A (pin) |
StickyImmix | Yes | No | No | Yes | Yes |
ConcurrentImmix | Yes | No | No | No | No |
LXR | Yes (fork) | No | No | No | No |
Iso | Yes (fork) | No | No | No | No |
Notes:
- “No” means the VM binding currently does not support that plan, but there is no technical factors that prevent the VM from using that plan.
- “N/A (reason)” means the plan is not applicable to the VM, i.e. the VM cannot use the
specified plans due to special VM requirements.
- “N/A (pin)” means the VM requires object pinning while the plan does not support object pinning.
- “WIP” means the support for the specified plan is currently under development.
- “Yes (fork)” means the plan is functional, but the code is still in a forked repository of mmtk-core or the VM binding, and has not been merged, yet. Such plans usually require non-trivial changes to mmtk-core or the VM binding, and take time to merge.
Performance
We track performance for a number of collectors in MMTk running with OpenJDK and JikesRVM. See here.