一、前言
对于多线程无锁的大数据应用场景需要在堆内存中及时有效释放对象,对于内存资源更好的加以利用,这边hessian提供HessianFreeList源码示例进行说明-基于java.util.concurrent.atomic.AtomicReferenceArray、java.util.concurrent.atomic.AtomicInteger实现原子对象序列存储及状态控制,具体代码见下
二、源码说明
package com.caucho.hessian.util;@b@@b@import java.util.concurrent.atomic.AtomicInteger;@b@import java.util.concurrent.atomic.AtomicReferenceArray;@b@@b@/**@b@ * FreeList provides a simple class to manage free objects. This is useful@b@ * for large data structures that otherwise would gobble up huge GC time.@b@ *@b@ * <p>The free list is bounded. Freeing an object when the list is full will@b@ * do nothing.@b@ */@b@public final class HessianFreeList<T> {@b@ private final AtomicReferenceArray<T> _freeStack;@b@ private final AtomicInteger _top = new AtomicInteger();@b@@b@ /**@b@ * Create a new free list.@b@ *@b@ * @param initialSize maximum number of free objects to store.@b@ */@b@ public HessianFreeList(int size)@b@ {@b@ _freeStack = new AtomicReferenceArray(size);@b@ }@b@ @b@ /**@b@ * Try to get an object from the free list. Returns null if the free list@b@ * is empty.@b@ *@b@ * @return the new object or null.@b@ */@b@ public T allocate()@b@ {@b@ int top = _top.get();@b@@b@ if (top > 0 && _top.compareAndSet(top, top - 1))@b@ return _freeStack.getAndSet(top - 1, null);@b@ else@b@ return null;@b@ }@b@ @b@ /**@b@ * Frees the object. If the free list is full, the object will be garbage@b@ * collected.@b@ *@b@ * @param obj the object to be freed.@b@ */@b@ public boolean free(T obj)@b@ {@b@ int top = _top.get();@b@@b@ if (top < _freeStack.length()) {@b@ boolean isFree = _freeStack.compareAndSet(top, null, obj);@b@ @b@ _top.compareAndSet(top, top + 1);@b@@b@ return isFree;@b@ }@b@ else@b@ return false;@b@ }@b@@b@ public boolean allowFree(T obj)@b@ {@b@ return _top.get() < _freeStack.length();@b@ }@b@@b@ /**@b@ * Frees the object. If the free list is full, the object will be garbage@b@ * collected.@b@ *@b@ * @param obj the object to be freed.@b@ */@b@ public void freeCareful(T obj)@b@ {@b@ if (checkDuplicate(obj))@b@ throw new IllegalStateException("tried to free object twice: " + obj);@b@@b@ free(obj);@b@ }@b@@b@ /**@b@ * Debugging to see if the object has already been freed.@b@ */@b@ public boolean checkDuplicate(T obj)@b@ {@b@ int top = _top.get();@b@@b@ for (int i = top - 1; i >= 0; i--) {@b@ if (_freeStack.get(i) == obj)@b@ return true;@b@ }@b@@b@ return false;@b@ }@b@}