CMM

CMM (Cooperative Memory Management) is my third attempt at a GC for Java (OpenJDK).

License

Apache for the API and concepts discussed here
GPL for the OpenJDK implementation

The concept

CMM exposes an API to the mutators for a finer control of the heap.
This is achieved by means of ScopedHeaps and the ability to manage their life-cycle by the mutators.
The API is kept very simple and it is up to the mutators to make proper use of it.
It is assumed that by using the CMM API the system will be able to manage memory more efficiently.
It is also assumed that a ScopedHeap's life-cycle is coupled with a transaction and should not be long lived.

API

public interface CMM {
	/** creates a new scoped heap */
	Heap createHeap();
	/** returns the Heap used by the current Thread */
	Heap getCurrentHeap();
	/** instructs the current thread to use the given scoped heap */
	void useHeap(Heap heap);
	/** instructs the current thread to use the global heap */
	void useGlobalHeap();
	/** gets the global heap */
	Heap getGlobalHeap();
}

public interface Heap {
	/** merges this heap with the given one */
	void merge(Heap heap);
	/** creates a heap reference to an object */
	HeapRef createRef(Object obj);

	/** instructs the system to collect the heap */
	void collect();
	/** disposes this heap, all associated heap references are nulled prior to disposal */
	void dispose();
}

public interface HeapRef {
	/** retrieves the object associated via this reference */
	Object getObject();
	/** retrieves the heap */
	Heap getHeap();
}
            

Use case 1 - directly within client code

public class Test3 {
    public static void main(String args[]) throws Exception {
        // bootstrap CMM
        Heap heap = CMM.createHeap();
        CMM.useHeap(heap);
        long start = System.currentTimeMillis();
        ArrayList list = new ArrayList();
        int count = 0;
        for (int i=0; ; i++) {
            Object[] data = new Object[1024/24];
            for (int j=0; j100)
                    break;
            }
        }
        // fallback to the global heap
        CMM.useGlobalHeap();
        // now dispose the heap altogether
        heap.dispose();
    }
}
            

Use case 2 - Servlet Filter / AOP

public class ScopedHeapFilter implements Filter {
    
    public void doFilter(ServletRequest req, ServletResponse res,
            FilterChain fc) throws IOException, ServletException {
        
        // bootstrap CMM
        Heap heap = CMM.createHeap();
        CMM.useHeap(heap);
        try {
            fc.doFilter(req, res);
        } finally {
            // fallback to the global heap
            CMM.useGlobalHeap();
            // now dispose the heap altogether
            heap.dispose();
        }
    }
    
    public void init(FilterConfig fc) throws ServletException {
    }
    
    public void destroy() {
    }
}
            

Implementation details

CMM uses a regional heap layout consisting of cmmPages and utilizes mark-sweep-compact as the core algorithm.
A cmmPage is a fixed sized range of memory (by power of 2, 2MB per default).
It also reserves a vast virtual address space into which cmmPages are mapped into (using mmap).
Having a vast virtual address space reduces the frequency of required heap compactions, thus minimizing GC cycles.
CMM uses a read and write barrier, thus GC can be performed concurrently with the mutators.

Project site

https://bitbucket.org/cmmgc/cmm-api/