geode-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From u..@apache.org
Subject [057/100] [abbrv] incubator-geode git commit: GEODE-831: unit test FreeListManager
Date Mon, 22 Feb 2016 21:43:45 GMT
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9899940b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/SimpleMemoryAllocatorImpl.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/SimpleMemoryAllocatorImpl.java b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/SimpleMemoryAllocatorImpl.java
index 12d297b..14bde59 100644
--- a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/SimpleMemoryAllocatorImpl.java
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/SimpleMemoryAllocatorImpl.java
@@ -55,47 +55,20 @@ import com.gemstone.gemfire.internal.offheap.annotations.Unretained;
  * @author Kirk Lund
  * @since 9.0
  */
-public final class SimpleMemoryAllocatorImpl implements MemoryAllocator {
+public class SimpleMemoryAllocatorImpl implements MemoryAllocator {
 
   static final Logger logger = LogService.getLogger();
   
   public static final String FREE_OFF_HEAP_MEMORY_PROPERTY = "gemfire.free-off-heap-memory";
   
-  /**
-   * How many extra allocations to do for each actual slab allocation.
-   * Is this really a good idea?
-   */
-  public static final int BATCH_SIZE = Integer.getInteger("gemfire.OFF_HEAP_BATCH_ALLOCATION_SIZE", 1);
-  /**
-   * Every allocated chunk smaller than TINY_MULTIPLE*TINY_FREE_LIST_COUNT will allocate a chunk of memory that is a multiple of this value.
-   * Sizes are always rounded up to the next multiple of this constant
-   * so internal fragmentation will be limited to TINY_MULTIPLE-1 bytes per allocation
-   * and on average will be TINY_MULTIPLE/2 given a random distribution of size requests.
-   * This does not account for the additional internal fragmentation caused by the off-heap header
-   * which currently is always 8 bytes.
-   */
-  public final static int TINY_MULTIPLE = Integer.getInteger("gemfire.OFF_HEAP_ALIGNMENT", 8);
-  /**
-   * Number of free lists to keep for tiny allocations.
-   */
-  public final static int TINY_FREE_LIST_COUNT = Integer.getInteger("gemfire.OFF_HEAP_FREE_LIST_COUNT", 16384);
-  public final static int MAX_TINY = TINY_MULTIPLE*TINY_FREE_LIST_COUNT;
-  /**
-   * How many unused bytes are allowed in a huge memory allocation.
-   */
-  public final static int HUGE_MULTIPLE = 256;
-  
-  volatile OffHeapMemoryStats stats;
+  private volatile OffHeapMemoryStats stats;
   
-  volatile OutOfOffHeapMemoryListener ooohml;
-  
-  /** The MemoryChunks that this allocator is managing by allocating smaller chunks of them.
-   * The contents of this array never change.
-   */
-  private final UnsafeMemoryChunk[] slabs;
-  private final long totalSlabSize;
-  private final int largestSlab;
+  private volatile OutOfOffHeapMemoryListener ooohml;
   
+  OutOfOffHeapMemoryListener getOutOfOffHeapMemoryListener() {
+    return this.ooohml;
+  }
+
   public final FreeListManager freeList;
 
   private MemoryInspector memoryInspector;
@@ -103,7 +76,6 @@ public final class SimpleMemoryAllocatorImpl implements MemoryAllocator {
   private volatile MemoryUsageListener[] memoryUsageListeners = new MemoryUsageListener[0];
   
   private static SimpleMemoryAllocatorImpl singleton = null;
-  final ChunkFactory chunkFactory;
   
   public static SimpleMemoryAllocatorImpl getAllocator() {
     SimpleMemoryAllocatorImpl result = singleton;
@@ -118,10 +90,9 @@ public final class SimpleMemoryAllocatorImpl implements MemoryAllocator {
   public static MemoryAllocator create(OutOfOffHeapMemoryListener ooohml, OffHeapMemoryStats stats, LogWriter lw, 
       int slabCount, long offHeapMemorySize, long maxSlabSize) {
     return create(ooohml, stats, lw, slabCount, offHeapMemorySize, maxSlabSize,
-        null, TINY_MULTIPLE, BATCH_SIZE, TINY_FREE_LIST_COUNT, HUGE_MULTIPLE, 
-        new UnsafeMemoryChunk.Factory() {
+        null, new AddressableMemoryChunkFactory() {
       @Override
-      public UnsafeMemoryChunk create(int size) {
+      public AddressableMemoryChunk create(int size) {
         return new UnsafeMemoryChunk(size);
       }
     });
@@ -129,15 +100,14 @@ public final class SimpleMemoryAllocatorImpl implements MemoryAllocator {
 
   private static SimpleMemoryAllocatorImpl create(OutOfOffHeapMemoryListener ooohml, OffHeapMemoryStats stats, LogWriter lw, 
       int slabCount, long offHeapMemorySize, long maxSlabSize, 
-      UnsafeMemoryChunk[] slabs, int tinyMultiple, int batchSize, int tinyFreeListCount, int hugeMultiple,
-      UnsafeMemoryChunk.Factory memChunkFactory) {
+      AddressableMemoryChunk[] slabs, AddressableMemoryChunkFactory memChunkFactory) {
     SimpleMemoryAllocatorImpl result = singleton;
     boolean created = false;
     try {
     if (result != null) {
       result.reuse(ooohml, lw, stats, offHeapMemorySize, slabs);
       if (lw != null) {
-        lw.config("Reusing " + result.getTotalMemory() + " bytes of off-heap memory. The maximum size of a single off-heap object is " + result.largestSlab + " bytes.");
+        lw.config("Reusing " + result.getTotalMemory() + " bytes of off-heap memory. The maximum size of a single off-heap object is " + result.freeList.getLargestSlabSize() + " bytes.");
       }
       created = true;
       LifecycleListener.invokeAfterReuse(result);
@@ -175,7 +145,7 @@ public final class SimpleMemoryAllocatorImpl implements MemoryAllocator {
         }
       }
 
-      result = new SimpleMemoryAllocatorImpl(ooohml, stats, slabs, tinyMultiple, batchSize, tinyFreeListCount, hugeMultiple);
+      result = new SimpleMemoryAllocatorImpl(ooohml, stats, slabs);
       singleton = result;
       LifecycleListener.invokeAfterCreate(result);
       created = true;
@@ -192,19 +162,12 @@ public final class SimpleMemoryAllocatorImpl implements MemoryAllocator {
     }
     return result;
   }
-  // for unit tests
-  static SimpleMemoryAllocatorImpl create(OutOfOffHeapMemoryListener ooohml, OffHeapMemoryStats stats, LogWriter lw, 
-      int slabCount, long offHeapMemorySize, long maxSlabSize, UnsafeMemoryChunk.Factory memChunkFactory) {
+  static SimpleMemoryAllocatorImpl createForUnitTest(OutOfOffHeapMemoryListener ooohml, OffHeapMemoryStats stats, LogWriter lw, 
+      int slabCount, long offHeapMemorySize, long maxSlabSize, AddressableMemoryChunkFactory memChunkFactory) {
     return create(ooohml, stats, lw, slabCount, offHeapMemorySize, maxSlabSize, 
-        null, TINY_MULTIPLE, BATCH_SIZE, TINY_FREE_LIST_COUNT, HUGE_MULTIPLE, memChunkFactory);
-  }
-  // for unit tests
-  public static SimpleMemoryAllocatorImpl create(OutOfOffHeapMemoryListener oooml, OffHeapMemoryStats stats, UnsafeMemoryChunk[] slabs) {
-    return create(oooml, stats, slabs, TINY_MULTIPLE, BATCH_SIZE, TINY_FREE_LIST_COUNT, HUGE_MULTIPLE);
+        null, memChunkFactory);
   }
-  // for unit tests
-  static SimpleMemoryAllocatorImpl create(OutOfOffHeapMemoryListener oooml, OffHeapMemoryStats stats, UnsafeMemoryChunk[] slabs,
-      int tinyMultiple, int batchSize, int tinyFreeListCount, int hugeMultiple) {
+  public static SimpleMemoryAllocatorImpl createForUnitTest(OutOfOffHeapMemoryListener oooml, OffHeapMemoryStats stats, AddressableMemoryChunk[] slabs) {
     int slabCount = 0;
     long offHeapMemorySize = 0;
     long maxSlabSize = 0;
@@ -218,11 +181,11 @@ public final class SimpleMemoryAllocatorImpl implements MemoryAllocator {
         }
       }
     }
-    return create(oooml, stats, null, slabCount, offHeapMemorySize, maxSlabSize, slabs, tinyMultiple, batchSize, tinyFreeListCount, hugeMultiple, null);
+    return create(oooml, stats, null, slabCount, offHeapMemorySize, maxSlabSize, slabs, null);
   }
   
   
-  private void reuse(OutOfOffHeapMemoryListener oooml, LogWriter lw, OffHeapMemoryStats newStats, long offHeapMemorySize, UnsafeMemoryChunk[] slabs) {
+  private void reuse(OutOfOffHeapMemoryListener oooml, LogWriter lw, OffHeapMemoryStats newStats, long offHeapMemorySize, AddressableMemoryChunk[] slabs) {
     if (isClosed()) {
       throw new IllegalStateException("Can not reuse a closed off-heap memory manager.");
     }
@@ -234,83 +197,47 @@ public final class SimpleMemoryAllocatorImpl implements MemoryAllocator {
         lw.warning("Using " + getTotalMemory() + " bytes of existing off-heap memory instead of the requested " + offHeapMemorySize);
       }
     }
-    if (slabs != null) {
-      // this will only happen in unit tests
-      if (slabs != this.slabs) {
-        // If the unit test gave us a different array
-        // of slabs then something is wrong because we
-        // are trying to reuse the old already allocated
-        // array which means that the new one will never
-        // be used. Note that this code does not bother
-        // comparing the contents of the arrays.
-        throw new IllegalStateException("attempted to reuse existing off-heap memory even though new off-heap memory was allocated");
-      }
+    if (!this.freeList.okToReuse(slabs)) {
+      throw new IllegalStateException("attempted to reuse existing off-heap memory even though new off-heap memory was allocated");
     }
     this.ooohml = oooml;
     newStats.initialize(this.stats);
     this.stats = newStats;
   }
 
-  private SimpleMemoryAllocatorImpl(final OutOfOffHeapMemoryListener oooml, final OffHeapMemoryStats stats, final UnsafeMemoryChunk[] slabs,
-      int tinyMultiple, int batchSize, int tinyFreeListCount, int hugeMultiple) {
+  private SimpleMemoryAllocatorImpl(final OutOfOffHeapMemoryListener oooml, final OffHeapMemoryStats stats, final AddressableMemoryChunk[] slabs) {
     if (oooml == null) {
       throw new IllegalArgumentException("OutOfOffHeapMemoryListener is null");
     }
-    if (tinyMultiple <= 0 || (tinyMultiple & 3) != 0) {
-      throw new IllegalStateException("gemfire.OFF_HEAP_ALIGNMENT must be a multiple of 8.");
-    }
-    if (tinyMultiple > 256) {
-      // this restriction exists because of the dataSize field in the object header.
-      throw new IllegalStateException("gemfire.OFF_HEAP_ALIGNMENT must be <= 256 and a multiple of 8.");
-    }
-    if (batchSize <= 0) {
-      throw new IllegalStateException("gemfire.OFF_HEAP_BATCH_ALLOCATION_SIZE must be >= 1.");
-    }
-    if (tinyFreeListCount <= 0) {
-      throw new IllegalStateException("gemfire.OFF_HEAP_FREE_LIST_COUNT must be >= 1.");
-    }
-    if (hugeMultiple > 256 || hugeMultiple < 0) {
-      // this restriction exists because of the dataSize field in the object header.
-      throw new IllegalStateException("HUGE_MULTIPLE must be >= 0 and <= 256 but it was " + hugeMultiple);
-    }
     
     this.ooohml = oooml;
     this.stats = stats;
-    this.slabs = slabs;
-    this.chunkFactory = new GemFireChunkFactory();
-    
+
     //OSProcess.printStacks(0, InternalDistributedSystem.getAnyInstance().getLogWriter(), false);
     this.stats.setFragments(slabs.length);
-    largestSlab = slabs[0].getSize();
-    this.stats.setLargestFragment(largestSlab);
-    long total = 0;
-    for (int i=0; i < slabs.length; i++) {
-      //debugLog("slab"+i + " @" + Long.toHexString(slabs[i].getMemoryAddress()), false);
-      //UnsafeMemoryChunk.clearAbsolute(slabs[i].getMemoryAddress(), slabs[i].getSize()); // HACK to see what this does to bug 47883
-      total += slabs[i].getSize();
-    }
-    totalSlabSize = total;
-    this.stats.incMaxMemory(this.totalSlabSize);
-    this.stats.incFreeMemory(this.totalSlabSize);
+    this.stats.setLargestFragment(slabs[0].getSize());
     
-    this.freeList = new FreeListManager(this);
+    this.freeList = new FreeListManager(this, slabs);
     this.memoryInspector = new MemoryInspectorImpl(this.freeList);
+
+    this.stats.incMaxMemory(this.freeList.getTotalMemory());
+    this.stats.incFreeMemory(this.freeList.getTotalMemory());
   }
   
-  public List<Chunk> getLostChunks() {
-    List<Chunk> liveChunks = this.freeList.getLiveChunks();
-    List<Chunk> regionChunks = getRegionLiveChunks();
-    Set<Chunk> liveChunksSet = new HashSet<>(liveChunks);
-    Set<Chunk> regionChunksSet = new HashSet<>(regionChunks);
+  public List<ObjectChunk> getLostChunks() {
+    List<ObjectChunk> liveChunks = this.freeList.getLiveChunks();
+    List<ObjectChunk> regionChunks = getRegionLiveChunks();
+    Set<ObjectChunk> liveChunksSet = new HashSet<>(liveChunks);
+    Set<ObjectChunk> regionChunksSet = new HashSet<>(regionChunks);
     liveChunksSet.removeAll(regionChunksSet);
-    return new ArrayList<Chunk>(liveChunksSet);
+    return new ArrayList<ObjectChunk>(liveChunksSet);
   }
   
   /**
    * Returns a possibly empty list that contains all the Chunks used by regions.
    */
-  private List<Chunk> getRegionLiveChunks() {
-    ArrayList<Chunk> result = new ArrayList<Chunk>();
+  private List<ObjectChunk> getRegionLiveChunks() {
+    ArrayList<ObjectChunk> result = new ArrayList<ObjectChunk>();
     RegionService gfc = GemFireCacheImpl.getInstance();
     if (gfc != null) {
       Iterator<Region<?,?>> rootIt = gfc.rootRegions().iterator();
@@ -326,7 +253,7 @@ public final class SimpleMemoryAllocatorImpl implements MemoryAllocator {
     return result;
   }
 
-  private void getRegionLiveChunks(Region<?,?> r, List<Chunk> result) {
+  private void getRegionLiveChunks(Region<?,?> r, List<ObjectChunk> result) {
     if (r.getAttributes().getOffHeap()) {
 
       if (r instanceof PartitionedRegion) {
@@ -350,7 +277,7 @@ public final class SimpleMemoryAllocatorImpl implements MemoryAllocator {
 
   }
   
-  private void basicGetRegionLiveChunks(LocalRegion r, List<Chunk> result) {
+  private void basicGetRegionLiveChunks(LocalRegion r, List<ObjectChunk> result) {
     for (Object key : r.keySet()) {
       RegionEntry re = ((LocalRegion) r).getRegionEntry(key);
       if (re != null) {
@@ -359,24 +286,34 @@ public final class SimpleMemoryAllocatorImpl implements MemoryAllocator {
          */
         @Unretained(OffHeapIdentifier.GATEWAY_SENDER_EVENT_IMPL_VALUE)
         Object value = re._getValue();
-        if (value instanceof Chunk) {
-          result.add((Chunk) value);
+        if (value instanceof ObjectChunk) {
+          result.add((ObjectChunk) value);
         }
       }
     }
   }
 
-  @Override
-  public MemoryChunk allocate(int size, ChunkType chunkType) {
-    //System.out.println("allocating " + size);
-    Chunk result = this.freeList.allocate(size, chunkType);
-    //("allocated off heap object of size " + size + " @" + Long.toHexString(result.getMemoryAddress()), true);
+  private ObjectChunk allocateChunk(int size) {
+    ObjectChunk result = this.freeList.allocate(size);
+    int resultSize = result.getSize();
+    stats.incObjects(1);
+    stats.incUsedMemory(resultSize);
+    stats.incFreeMemory(-resultSize);
+    notifyListeners();
     if (ReferenceCountHelper.trackReferenceCounts()) {
       ReferenceCountHelper.refCountChanged(result.getMemoryAddress(), false, 1);
     }
     return result;
   }
   
+  @Override
+  public MemoryChunk allocate(int size) {
+    //System.out.println("allocating " + size);
+    ObjectChunk result = allocateChunk(size);
+    //("allocated off heap object of size " + size + " @" + Long.toHexString(result.getMemoryAddress()), true);
+    return result;
+  }
+  
   public static void debugLog(String msg, boolean logStack) {
     if (logStack) {
       logger.info(msg, new RuntimeException(msg));
@@ -386,22 +323,14 @@ public final class SimpleMemoryAllocatorImpl implements MemoryAllocator {
   }
   
   @Override
-  public StoredObject allocateAndInitialize(byte[] v, boolean isSerialized, boolean isCompressed, ChunkType chunkType) {
+  public StoredObject allocateAndInitialize(byte[] v, boolean isSerialized, boolean isCompressed) {
     long addr = OffHeapRegionEntryHelper.encodeDataAsAddress(v, isSerialized, isCompressed);
     if (addr != 0L) {
       return new DataAsAddress(addr);
     }
-    if (chunkType == null) {
-      chunkType = GemFireChunk.TYPE;
-    }
-
-    Chunk result = this.freeList.allocate(v.length, chunkType);
+    ObjectChunk result = allocateChunk(v.length);
     //debugLog("allocated off heap object of size " + v.length + " @" + Long.toHexString(result.getMemoryAddress()), true);
     //debugLog("allocated off heap object of size " + v.length + " @" + Long.toHexString(result.getMemoryAddress()) +  "chunkSize=" + result.getSize() + " isSerialized=" + isSerialized + " v=" + Arrays.toString(v), true);
-    if (ReferenceCountHelper.trackReferenceCounts()) {
-      ReferenceCountHelper.refCountChanged(result.getMemoryAddress(), false, 1);
-    }
-    assert result.getChunkType() == chunkType: "chunkType=" + chunkType + " getChunkType()=" + result.getChunkType();
     result.setSerializedValue(v);
     result.setSerialized(isSerialized);
     result.setCompressed(isCompressed);
@@ -420,7 +349,7 @@ public final class SimpleMemoryAllocatorImpl implements MemoryAllocator {
 
   @Override
   public long getTotalMemory() {
-    return totalSlabSize;
+    return this.freeList.getTotalMemory();
   }
   
   @Override
@@ -445,7 +374,7 @@ public final class SimpleMemoryAllocatorImpl implements MemoryAllocator {
   private void realClose() {
     // Removing this memory immediately can lead to a SEGV. See 47885.
     if (setClosed()) {
-      freeSlabs(this.slabs);
+      this.freeList.freeSlabs();
       this.stats.close();
       singleton = null;
     }
@@ -464,45 +393,21 @@ public final class SimpleMemoryAllocatorImpl implements MemoryAllocator {
   }
   
 
-  private static void freeSlabs(final UnsafeMemoryChunk[] slabs) {
-    //debugLog("called freeSlabs", false);
-    for (int i=0; i < slabs.length; i++) {
-      slabs[i].release();
-    }
-  }
-  
-  void freeChunk(long addr) {
-    this.freeList.free(addr);
-  }
-  
-  protected UnsafeMemoryChunk[] getSlabs() {
-    return this.slabs;
+  FreeListManager getFreeListManager() {
+    return this.freeList;
   }
   
   /**
    * Return the slabId of the slab that contains the given addr.
    */
   int findSlab(long addr) {
-    for (int i=0; i < this.slabs.length; i++) {
-      UnsafeMemoryChunk slab = this.slabs[i];
-      long slabAddr = slab.getMemoryAddress();
-      if (addr >= slabAddr) {
-        if (addr < slabAddr + slab.getSize()) {
-          return i;
-        }
-      }
-    }
-    throw new IllegalStateException("could not find a slab for addr " + addr);
+    return this.freeList.findSlab(addr);
   }
   
   public OffHeapMemoryStats getStats() {
     return this.stats;
   }
   
-  public ChunkFactory getChunkFactory() {
-    return this.chunkFactory;
-  }
-
   @Override
   public void addMemoryUsageListener(final MemoryUsageListener listener) {
     synchronized (this.memoryUsageListeners) {
@@ -558,12 +463,8 @@ public final class SimpleMemoryAllocatorImpl implements MemoryAllocator {
       SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.singleton;
       if (ma != null) {
         sb.append(". Valid addresses must be in one of the following ranges: ");
-        for (int i=0; i < ma.slabs.length; i++) {
-          long startAddr = ma.slabs[i].getMemoryAddress();
-          long endAddr = startAddr + ma.slabs[i].getSize();
-          sb.append("[").append(Long.toString(startAddr, 16)).append("..").append(Long.toString(endAddr, 16)).append("] ");
-        }
-      }
+        ma.freeList.getSlabDescriptions(sb);
+     }
       throw new IllegalStateException(sb.toString());
     }
     if (addr >= 0 && addr < 1024) {
@@ -576,28 +477,19 @@ public final class SimpleMemoryAllocatorImpl implements MemoryAllocator {
     if (doExpensiveValidation) {
       SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.singleton;
       if (ma != null) {
-        for (int i=0; i < ma.slabs.length; i++) {
-          if (ma.slabs[i].getMemoryAddress() <= addr && addr < (ma.slabs[i].getMemoryAddress() + ma.slabs[i].getSize())) {
-            // validate addr + size is within the same slab
-            if (size != -1) { // skip this check if size is -1
-              if (!(ma.slabs[i].getMemoryAddress() <= (addr+size-1) && (addr+size-1) < (ma.slabs[i].getMemoryAddress() + ma.slabs[i].getSize()))) {
-                throw new IllegalStateException(" address 0x" + Long.toString(addr+size-1, 16) + " does not address the original slab memory");
-              }
-            }
-            return;
-          }
+        if (!ma.freeList.validateAddressAndSizeWithinSlab(addr, size)) {
+          throw new IllegalStateException(" address 0x" + Long.toString(addr, 16) + " does not address the original slab memory");
         }
-        throw new IllegalStateException(" address 0x" + Long.toString(addr, 16) + " does not address the original slab memory");
       }
     }
   }
 
   public synchronized List<MemoryBlock> getOrphans() {
-    List<Chunk> liveChunks = this.freeList.getLiveChunks();
-    List<Chunk> regionChunks = getRegionLiveChunks();
+    List<ObjectChunk> liveChunks = this.freeList.getLiveChunks();
+    List<ObjectChunk> regionChunks = getRegionLiveChunks();
     liveChunks.removeAll(regionChunks);
     List<MemoryBlock> orphans = new ArrayList<MemoryBlock>();
-    for (Chunk chunk: liveChunks) {
+    for (ObjectChunk chunk: liveChunks) {
       orphans.add(new MemoryBlockNode(this, chunk));
     }
     Collections.sort(orphans,
@@ -615,11 +507,5 @@ public final class SimpleMemoryAllocatorImpl implements MemoryAllocator {
   public MemoryInspector getMemoryInspector() {
     return this.memoryInspector;
   }
-
-  /*
-   * Set this to "true" to perform data integrity checks on allocated and reused Chunks.  This may clobber 
-   * performance so turn on only when necessary.
-   */
-  final boolean validateMemoryWithFill = Boolean.getBoolean("gemfire.validateOffHeapWithFill");
   
 }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9899940b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/SyncChunkStack.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/SyncChunkStack.java b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/SyncChunkStack.java
index 7ba28a2..99fd96f 100644
--- a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/SyncChunkStack.java
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/SyncChunkStack.java
@@ -42,7 +42,7 @@ public class SyncChunkStack {
     assert e != 0;
     SimpleMemoryAllocatorImpl.validateAddress(e);
     synchronized (this) {
-      Chunk.setNext(e, this.topAddr);
+      ObjectChunk.setNext(e, this.topAddr);
       this.topAddr = e;
     }
   }
@@ -51,7 +51,7 @@ public class SyncChunkStack {
     synchronized (this) {
       result = this.topAddr;
       if (result != 0L) {
-        this.topAddr = Chunk.getNext(result);
+        this.topAddr = ObjectChunk.getNext(result);
       }
     }
     return result;
@@ -85,8 +85,8 @@ public class SyncChunkStack {
       concurrentModDetected = false;
       addr = headAddr;
       while (addr != 0L) {
-        int curSize = Chunk.getSize(addr);
-        addr = Chunk.getNext(addr);
+        int curSize = ObjectChunk.getSize(addr);
+        addr = ObjectChunk.getNext(addr);
         testHookDoConcurrentModification();
         long curHead = this.topAddr;
         if (curHead != headAddr) {
@@ -113,8 +113,8 @@ public class SyncChunkStack {
       result = 0;
       addr = headAddr;
       while (addr != 0L) {
-        result += Chunk.getSize(addr);
-        addr = Chunk.getNext(addr);
+        result += ObjectChunk.getSize(addr);
+        addr = ObjectChunk.getNext(addr);
         testHookDoConcurrentModification();
         long curHead = this.topAddr;
         if (curHead != headAddr) {

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9899940b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/UnsafeMemoryChunk.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/UnsafeMemoryChunk.java b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/UnsafeMemoryChunk.java
index ed1c843..aebc459 100644
--- a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/UnsafeMemoryChunk.java
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/UnsafeMemoryChunk.java
@@ -25,7 +25,7 @@ import com.gemstone.gemfire.pdx.internal.unsafe.UnsafeWrapper;
  * 
  * @since 9.0
  */
-public class UnsafeMemoryChunk implements MemoryChunk {
+public class UnsafeMemoryChunk implements AddressableMemoryChunk {
   private static final UnsafeWrapper unsafe;
   private static final int ARRAY_BYTE_BASE_OFFSET;
   private static String reason;
@@ -70,6 +70,10 @@ public class UnsafeMemoryChunk implements MemoryChunk {
     return (int)this.size;
   }
   
+  /* (non-Javadoc)
+   * @see com.gemstone.gemfire.internal.offheap.AddressableMemoryChunk#getMemoryAddress()
+   */
+  @Override
   public long getMemoryAddress() {
     return this.data;
   }
@@ -210,14 +214,4 @@ public class UnsafeMemoryChunk implements MemoryChunk {
     sb.append("}");
     return sb.toString();
   }
-  
-  /**
-   * Used to create UnsafeMemoryChunk instances.
-   */
-  public interface Factory {
-    /** Create and return an UnsafeMemoryChunk.
-     * @throws OutOfMemoryError if the create fails
-     */
-    public UnsafeMemoryChunk create(int size);
-  }
 }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9899940b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/tcp/ByteBufferInputStream.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/tcp/ByteBufferInputStream.java b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/tcp/ByteBufferInputStream.java
index 8a7d351..cfc05f2 100644
--- a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/tcp/ByteBufferInputStream.java
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/tcp/ByteBufferInputStream.java
@@ -31,7 +31,7 @@ import java.nio.ByteOrder;
 
 import com.gemstone.gemfire.internal.ByteBufferWriter;
 import com.gemstone.gemfire.internal.HeapDataOutputStream;
-import com.gemstone.gemfire.internal.offheap.Chunk;
+import com.gemstone.gemfire.internal.offheap.ObjectChunk;
 import com.gemstone.gemfire.internal.offheap.UnsafeMemoryChunk;
 
 /**
@@ -109,7 +109,7 @@ public class ByteBufferInputStream extends InputStream implements DataInput, jav
     public static ByteSource create(ByteBuffer bb) {
       return new ByteBufferByteSource(bb);
     }
-    public static ByteSource create(Chunk chunk) {
+    public static ByteSource create(ObjectChunk chunk) {
       // Since I found a way to create a DirectByteBuffer (using reflection) from a Chunk
       // we might not even need the ByteSource abstraction any more.
       // But it is possible that createByteBuffer will not work on a different jdk so keep it for now.
@@ -323,9 +323,9 @@ public class ByteBufferInputStream extends InputStream implements DataInput, jav
   public static class OffHeapByteSource implements ByteSource {
     private int position;
     private int limit;
-    private final Chunk chunk;
+    private final ObjectChunk chunk;
 
-    public OffHeapByteSource(Chunk c) {
+    public OffHeapByteSource(ObjectChunk c) {
       this.chunk = c;
       this.position = 0;
       this.limit = capacity();
@@ -724,7 +724,7 @@ public class ByteBufferInputStream extends InputStream implements DataInput, jav
     this.buffer = copy.buffer.duplicate();
   }
 
-  public ByteBufferInputStream(Chunk blob) {
+  public ByteBufferInputStream(ObjectChunk blob) {
     this.buffer = ByteSourceFactory.create(blob);
   }
 

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9899940b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/tcp/ImmutableByteBufferInputStream.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/tcp/ImmutableByteBufferInputStream.java b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/tcp/ImmutableByteBufferInputStream.java
index 52f332f..d632158 100644
--- a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/tcp/ImmutableByteBufferInputStream.java
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/tcp/ImmutableByteBufferInputStream.java
@@ -18,7 +18,7 @@ package com.gemstone.gemfire.internal.tcp;
 
 import java.nio.ByteBuffer;
 
-import com.gemstone.gemfire.internal.offheap.Chunk;
+import com.gemstone.gemfire.internal.offheap.ObjectChunk;
 
 /**
  * You should only create an instance of this class if the bytes this buffer reads
@@ -67,7 +67,7 @@ public class ImmutableByteBufferInputStream extends ByteBufferInputStream {
     // for serialization
   }
   
-  public ImmutableByteBufferInputStream(Chunk blob) {
+  public ImmutableByteBufferInputStream(ObjectChunk blob) {
     super(blob);
   }
   @Override

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9899940b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/util/BlobHelper.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/util/BlobHelper.java b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/util/BlobHelper.java
index 7a4840e..40015a4 100644
--- a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/util/BlobHelper.java
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/util/BlobHelper.java
@@ -27,7 +27,7 @@ import com.gemstone.gemfire.internal.DSCODE;
 import com.gemstone.gemfire.internal.HeapDataOutputStream;
 import com.gemstone.gemfire.internal.Version;
 import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
-import com.gemstone.gemfire.internal.offheap.Chunk;
+import com.gemstone.gemfire.internal.offheap.ObjectChunk;
 import com.gemstone.gemfire.internal.offheap.annotations.Unretained;
 import com.gemstone.gemfire.pdx.internal.PdxInputStream;
 
@@ -140,7 +140,7 @@ public class BlobHelper {
    * If a PdxInstance is returned then it will refer to Chunk's off-heap memory
    * with an unretained reference.
    */
-  public static @Unretained Object deserializeOffHeapBlob(Chunk blob) throws IOException, ClassNotFoundException {
+  public static @Unretained Object deserializeOffHeapBlob(ObjectChunk blob) throws IOException, ClassNotFoundException {
     Object result;
     final long start = startDeserialization();
     // For both top level and nested pdxs we just want a reference to this off-heap blob.

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9899940b/gemfire-core/src/main/java/com/gemstone/gemfire/pdx/internal/PdxInputStream.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/pdx/internal/PdxInputStream.java b/gemfire-core/src/main/java/com/gemstone/gemfire/pdx/internal/PdxInputStream.java
index 85e078d..4a5a9df 100644
--- a/gemfire-core/src/main/java/com/gemstone/gemfire/pdx/internal/PdxInputStream.java
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/pdx/internal/PdxInputStream.java
@@ -26,7 +26,7 @@ import java.util.Date;
 import com.gemstone.gemfire.DataSerializer;
 import com.gemstone.gemfire.InternalGemFireException;
 import com.gemstone.gemfire.pdx.PdxSerializationException;
-import com.gemstone.gemfire.internal.offheap.Chunk;
+import com.gemstone.gemfire.internal.offheap.ObjectChunk;
 import com.gemstone.gemfire.internal.tcp.ByteBufferInputStream;
 import com.gemstone.gemfire.internal.tcp.ImmutableByteBufferInputStream;
 
@@ -76,7 +76,7 @@ public class PdxInputStream extends ImmutableByteBufferInputStream {
     // for serialization
   }
 
-  public PdxInputStream(Chunk blob) {
+  public PdxInputStream(ObjectChunk blob) {
     super(blob);
   }
 

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9899940b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/cache/ChunkValueWrapperJUnitTest.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/internal/cache/ChunkValueWrapperJUnitTest.java b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/cache/ChunkValueWrapperJUnitTest.java
index 0606387..b69f82e 100644
--- a/gemfire-core/src/test/java/com/gemstone/gemfire/internal/cache/ChunkValueWrapperJUnitTest.java
+++ b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/cache/ChunkValueWrapperJUnitTest.java
@@ -29,7 +29,7 @@ import org.junit.experimental.categories.Category;
 
 import com.gemstone.gemfire.internal.cache.DiskEntry.Helper.ChunkValueWrapper;
 import com.gemstone.gemfire.internal.cache.DiskEntry.Helper.Flushable;
-import com.gemstone.gemfire.internal.offheap.Chunk;
+import com.gemstone.gemfire.internal.offheap.ObjectChunk;
 import com.gemstone.gemfire.internal.offheap.NullOffHeapMemoryStats;
 import com.gemstone.gemfire.internal.offheap.NullOutOfOffHeapMemoryListener;
 import com.gemstone.gemfire.internal.offheap.SimpleMemoryAllocatorImpl;
@@ -40,13 +40,13 @@ import com.gemstone.gemfire.test.junit.categories.UnitTest;
 public class ChunkValueWrapperJUnitTest {
 
   private static ChunkValueWrapper createChunkValueWrapper(byte[] bytes, boolean isSerialized) {
-    Chunk c = (Chunk)SimpleMemoryAllocatorImpl.getAllocator().allocateAndInitialize(bytes, isSerialized, false, null);
+    ObjectChunk c = (ObjectChunk)SimpleMemoryAllocatorImpl.getAllocator().allocateAndInitialize(bytes, isSerialized, false);
     return new ChunkValueWrapper(c);
   }
 
   @Before
   public void setUp() throws Exception {
-    SimpleMemoryAllocatorImpl.create(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{new UnsafeMemoryChunk(1024*1024)});
+    SimpleMemoryAllocatorImpl.createForUnitTest(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{new UnsafeMemoryChunk(1024*1024)});
   }
 
   @After

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9899940b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/cache/OldValueImporterTestBase.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/internal/cache/OldValueImporterTestBase.java b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/cache/OldValueImporterTestBase.java
index f7d0714..690b55a 100644
--- a/gemfire-core/src/test/java/com/gemstone/gemfire/internal/cache/OldValueImporterTestBase.java
+++ b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/cache/OldValueImporterTestBase.java
@@ -26,7 +26,7 @@ import org.junit.Test;
 
 import com.gemstone.gemfire.internal.HeapDataOutputStream;
 import com.gemstone.gemfire.internal.cache.EntryEventImpl.OldValueImporter;
-import com.gemstone.gemfire.internal.offheap.Chunk;
+import com.gemstone.gemfire.internal.offheap.ObjectChunk;
 import com.gemstone.gemfire.internal.offheap.DataAsAddress;
 import com.gemstone.gemfire.internal.offheap.NullOffHeapMemoryStats;
 import com.gemstone.gemfire.internal.offheap.NullOutOfOffHeapMemoryListener;
@@ -110,10 +110,10 @@ public abstract class OldValueImporterTestBase {
     // off-heap DataAsAddress byte array
     {
       SimpleMemoryAllocatorImpl sma =
-          SimpleMemoryAllocatorImpl.create(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{new UnsafeMemoryChunk(1024*1024)});
+          SimpleMemoryAllocatorImpl.createForUnitTest(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{new UnsafeMemoryChunk(1024*1024)});
       try {
         byte[] baValue = new byte[] {1,2};
-        DataAsAddress baValueSO = (DataAsAddress) sma.allocateAndInitialize(baValue, false, false, null);
+        DataAsAddress baValueSO = (DataAsAddress) sma.allocateAndInitialize(baValue, false, false);
         OldValueImporter omsg = createImporter();
         omsg.importOldObject(baValueSO, false);
         hdos = new HeapDataOutputStream(bytes);
@@ -127,10 +127,10 @@ public abstract class OldValueImporterTestBase {
     // off-heap Chunk byte array
     {
       SimpleMemoryAllocatorImpl sma =
-          SimpleMemoryAllocatorImpl.create(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{new UnsafeMemoryChunk(1024*1024)});
+          SimpleMemoryAllocatorImpl.createForUnitTest(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{new UnsafeMemoryChunk(1024*1024)});
       try {
         byte[] baValue = new byte[] {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17};
-        Chunk baValueSO = (Chunk) sma.allocateAndInitialize(baValue, false, false, null);
+        ObjectChunk baValueSO = (ObjectChunk) sma.allocateAndInitialize(baValue, false, false);
         OldValueImporter omsg = createImporter();
         omsg.importOldObject(baValueSO, false);
         hdos = new HeapDataOutputStream(bytes);
@@ -144,11 +144,11 @@ public abstract class OldValueImporterTestBase {
     // off-heap DataAsAddress String
     {
       SimpleMemoryAllocatorImpl sma =
-          SimpleMemoryAllocatorImpl.create(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{new UnsafeMemoryChunk(1024*1024)});
+          SimpleMemoryAllocatorImpl.createForUnitTest(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{new UnsafeMemoryChunk(1024*1024)});
       try {
         String baValue = "12";
         byte[] baValueBlob = BlobHelper.serializeToBlob(baValue);
-        DataAsAddress baValueSO = (DataAsAddress) sma.allocateAndInitialize(baValueBlob, true, false, null);
+        DataAsAddress baValueSO = (DataAsAddress) sma.allocateAndInitialize(baValueBlob, true, false);
         OldValueImporter omsg = createImporter();
         omsg.importOldObject(baValueSO, true);
         hdos = new HeapDataOutputStream(bytes);
@@ -162,11 +162,11 @@ public abstract class OldValueImporterTestBase {
     // off-heap Chunk String
     {
       SimpleMemoryAllocatorImpl sma =
-          SimpleMemoryAllocatorImpl.create(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{new UnsafeMemoryChunk(1024*1024)});
+          SimpleMemoryAllocatorImpl.createForUnitTest(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{new UnsafeMemoryChunk(1024*1024)});
       try {
         String baValue = "12345678";
         byte[] baValueBlob = BlobHelper.serializeToBlob(baValue);
-        Chunk baValueSO = (Chunk) sma.allocateAndInitialize(baValueBlob, true, false, null);
+        ObjectChunk baValueSO = (ObjectChunk) sma.allocateAndInitialize(baValueBlob, true, false);
         OldValueImporter omsg = createImporter();
         omsg.importOldObject(baValueSO, true);
         hdos = new HeapDataOutputStream(bytes);

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9899940b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/ChunkWithHeapFormJUnitTest.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/ChunkWithHeapFormJUnitTest.java b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/ChunkWithHeapFormJUnitTest.java
deleted file mode 100644
index bc32367..0000000
--- a/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/ChunkWithHeapFormJUnitTest.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.gemstone.gemfire.internal.offheap;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNotSame;
-import static org.junit.Assert.assertSame;
-
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-
-import com.gemstone.gemfire.test.junit.categories.UnitTest;
-
-@Category(UnitTest.class)
-public class ChunkWithHeapFormJUnitTest extends GemFireChunkJUnitTest {
-
-  @Test
-  public void getRawBytesShouldReturnCachedHeapForm() {
-    GemFireChunk chunk = createValueAsUnserializedStoredObject(getValue());
-
-    byte[] valueInBytes = getValueAsByteArray();
-    ChunkWithHeapForm heapForm = new ChunkWithHeapForm(chunk, valueInBytes);
-
-    assertNotNull(heapForm);
-
-    assertSame(valueInBytes, heapForm.getRawBytes());
-  }
-
-  @Test
-  public void getChunkWithoutHeapFormShouldReturnGemFireChunk() {
-    GemFireChunk chunk = createValueAsSerializedStoredObject(getValue());
-
-    byte[] valueInBytes = getValueAsByteArray();
-    ChunkWithHeapForm heapForm = new ChunkWithHeapForm(chunk, valueInBytes);
-
-    Chunk chunkWithOutHeapForm = heapForm.getChunkWithoutHeapForm();
-
-    assertNotNull(chunkWithOutHeapForm);
-    assertEquals(GemFireChunk.class, chunkWithOutHeapForm.getClass());
-
-    assertEquals(chunk, heapForm.getChunkWithoutHeapForm());
-
-    assertEquals(chunk.getMemoryAddress(), chunkWithOutHeapForm.getMemoryAddress());
-    assertArrayEquals(chunk.getRawBytes(), chunkWithOutHeapForm.getRawBytes());
-    assertNotSame(valueInBytes, chunkWithOutHeapForm.getRawBytes());
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9899940b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/FragmentJUnitTest.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/FragmentJUnitTest.java b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/FragmentJUnitTest.java
index ccc6b67..54eac9e 100644
--- a/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/FragmentJUnitTest.java
+++ b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/FragmentJUnitTest.java
@@ -18,7 +18,6 @@
 package com.gemstone.gemfire.internal.offheap;
 
 import static org.junit.Assert.*;
-import static org.mockito.Mockito.mock;
 import static org.hamcrest.CoreMatchers.*;
 
 import java.util.Arrays;
@@ -33,19 +32,12 @@ import org.junit.Test;
 import org.junit.experimental.categories.Category;
 import org.junit.rules.ExpectedException;
 
-import com.gemstone.gemfire.LogWriter;
 import com.gemstone.gemfire.test.junit.categories.UnitTest;
 
 @Category(UnitTest.class)
 public class FragmentJUnitTest {
 
-  private SimpleMemoryAllocatorImpl ma;
-  private OutOfOffHeapMemoryListener ooohml;
-  private OffHeapMemoryStats stats;
-  private LogWriter lw;
-  private UnsafeMemoryChunk.Factory umcFactory;
   private UnsafeMemoryChunk[] slabs;
-  private int numSlabs;
 
   static {
     ClassLoader.getSystemClassLoader().setDefaultAssertionStatus(true);
@@ -68,30 +60,18 @@ public class FragmentJUnitTest {
 
   @Before
   public void setUp() throws Exception {
-    ooohml = mock(OutOfOffHeapMemoryListener.class);
-    stats = mock(OffHeapMemoryStats.class);
-    lw = mock(LogWriter.class);
-    
-    numSlabs = 2;
-    umcFactory = new UnsafeMemoryChunk.Factory(){
-      @Override
-      public UnsafeMemoryChunk create(int size) {
-        return new UnsafeMemoryChunk(size);
-      }
-    };
-    slabs = allocateMemorySlabs();
+    UnsafeMemoryChunk slab1 = new UnsafeMemoryChunk((int)OffHeapStorage.MIN_SLAB_SIZE);
+    UnsafeMemoryChunk slab2 = new UnsafeMemoryChunk((int)OffHeapStorage.MIN_SLAB_SIZE);
+    slabs = new UnsafeMemoryChunk[]{slab1, slab2};
   }
 
   @After
   public void tearDown() throws Exception {
-    SimpleMemoryAllocatorImpl.freeOffHeapMemory();
+    for (int i=0; i < slabs.length; i++) {
+      slabs[i].release();
+    }
   }
   
-  private UnsafeMemoryChunk[] allocateMemorySlabs() {
-    ma = SimpleMemoryAllocatorImpl.create(ooohml, stats, lw, numSlabs, OffHeapStorage.MIN_SLAB_SIZE * numSlabs, OffHeapStorage.MIN_SLAB_SIZE, umcFactory);
-    return ma.getSlabs();
-  }
-
   
   @Test
   public void fragmentConstructorThrowsExceptionForNon8ByteAlignedAddress() {
@@ -147,7 +127,6 @@ public class FragmentJUnitTest {
   
   @Test
   public void getStateIsAlwaysStateUNUSED() {
-    slabs = allocateMemorySlabs();
     Fragment fragment = new Fragment(slabs[0].getMemoryAddress(), slabs[0].getSize());
     softly.assertThat(fragment.getState()).isEqualTo(MemoryBlock.State.UNUSED);
     fragment.allocate(fragment.getFreeIndex(), fragment.getFreeIndex() + 256);
@@ -156,7 +135,6 @@ public class FragmentJUnitTest {
 
   @Test
   public void getFreeListIdIsAlwaysMinus1() {
-    slabs = allocateMemorySlabs();
     Fragment fragment = new Fragment(slabs[0].getMemoryAddress(), slabs[0].getSize());
     softly.assertThat(fragment.getFreeListId()).isEqualTo(-1);
     fragment.allocate(fragment.getFreeIndex(), fragment.getFreeIndex() + 256);
@@ -165,7 +143,6 @@ public class FragmentJUnitTest {
 
   @Test
   public void getRefCountIsAlwaysZero() {
-    slabs = allocateMemorySlabs();
     Fragment fragment = new Fragment(slabs[0].getMemoryAddress(), slabs[0].getSize());
     softly.assertThat(fragment.getRefCount()).isEqualTo(0);
     fragment.allocate(fragment.getFreeIndex(), fragment.getFreeIndex() + 256);
@@ -174,7 +151,6 @@ public class FragmentJUnitTest {
 
   @Test
   public void getDataTypeIsAlwaysNA() {
-    slabs = allocateMemorySlabs();
     Fragment fragment = new Fragment(slabs[0].getMemoryAddress(), slabs[0].getSize());
     softly.assertThat(fragment.getDataType()).isEqualTo("N/A");
     fragment.allocate(fragment.getFreeIndex(), fragment.getFreeIndex() + 256);
@@ -183,7 +159,6 @@ public class FragmentJUnitTest {
 
   @Test
   public void isSerializedIsAlwaysFalse() {
-    slabs = allocateMemorySlabs();
     Fragment fragment = new Fragment(slabs[0].getMemoryAddress(), slabs[0].getSize());
     softly.assertThat(fragment.isSerialized()).isEqualTo(false);
     fragment.allocate(fragment.getFreeIndex(), fragment.getFreeIndex() + 256);
@@ -192,7 +167,6 @@ public class FragmentJUnitTest {
 
   @Test
   public void isCompressedIsAlwaysFalse() {
-    slabs = allocateMemorySlabs();
     Fragment fragment = new Fragment(slabs[0].getMemoryAddress(), slabs[0].getSize());
     softly.assertThat(fragment.isCompressed()).isEqualTo(false);
     fragment.allocate(fragment.getFreeIndex(), fragment.getFreeIndex() + 256);
@@ -201,7 +175,6 @@ public class FragmentJUnitTest {
 
   @Test
   public void getDataValueIsAlwaysNull() {
-    slabs = allocateMemorySlabs();
     Fragment fragment = new Fragment(slabs[0].getMemoryAddress(), slabs[0].getSize());
     softly.assertThat(fragment.getDataValue()).isNull();
     fragment.allocate(fragment.getFreeIndex(), fragment.getFreeIndex() + 256);
@@ -209,17 +182,7 @@ public class FragmentJUnitTest {
   }
 
   @Test
-  public void getChunkTypeIsAlwaysNull() {
-    slabs = allocateMemorySlabs();
-    Fragment fragment = new Fragment(slabs[0].getMemoryAddress(), slabs[0].getSize());
-    softly.assertThat(fragment.getChunkType()).isNull();
-    fragment.allocate(fragment.getFreeIndex(), fragment.getFreeIndex() + 256);
-    softly.assertThat(fragment.getChunkType()).isNull();
-  }
-
-  @Test
   public void fragmentEqualsComparesMemoryBlockAddresses() {
-    slabs = allocateMemorySlabs();
     Fragment fragment0 = new Fragment(slabs[0].getMemoryAddress(), slabs[0].getSize());
     Fragment sameFragment = new Fragment(slabs[0].getMemoryAddress(), slabs[0].getSize());
     Fragment fragment1 = new Fragment(slabs[1].getMemoryAddress(), slabs[1].getSize());
@@ -229,14 +192,12 @@ public class FragmentJUnitTest {
 
   @Test
   public void fragmentEqualsIsFalseForNonFragmentObjects() {
-    slabs = allocateMemorySlabs();
     Fragment fragment0 = new Fragment(slabs[0].getMemoryAddress(), slabs[0].getSize());
     assertThat(fragment0.equals(slabs[0]), is(false));
   }
 
   @Test
   public void fragmentHashCodeIsHashCodeOfItsMemoryAddress() {
-    slabs = allocateMemorySlabs();
     Fragment fragment0 = new Fragment(slabs[0].getMemoryAddress(), slabs[0].getSize());
     Fragment fragment1 = new Fragment(slabs[1].getMemoryAddress(), slabs[1].getSize());
     Long fragmentAddress = fragment0.getMemoryAddress();
@@ -246,12 +207,11 @@ public class FragmentJUnitTest {
 
   @Test
   public void fragmentFillSetsAllBytesToTheSameConstantValue() {
-    slabs = allocateMemorySlabs();
     Fragment fragment = new Fragment(slabs[0].getMemoryAddress(), slabs[0].getSize());
     Long fragmentAddress = fragment.getMemoryAddress();
     byte[] bytes = new byte[(int)OffHeapStorage.MIN_SLAB_SIZE];
     byte[] expectedBytes = new byte[(int)OffHeapStorage.MIN_SLAB_SIZE];
-    Arrays.fill(expectedBytes, Chunk.FILL_BYTE);;
+    Arrays.fill(expectedBytes, ObjectChunk.FILL_BYTE);;
     fragment.fill();
     UnsafeMemoryChunk.readAbsoluteBytes(fragmentAddress, bytes, 0, (int)OffHeapStorage.MIN_SLAB_SIZE);
     assertThat(bytes, is(equalTo(expectedBytes)));
@@ -261,7 +221,6 @@ public class FragmentJUnitTest {
   public void getNextBlockThrowsExceptionForFragment() {
     expectedException.expect(UnsupportedOperationException.class);
 
-    slabs = allocateMemorySlabs();
     Fragment fragment = new Fragment(slabs[0].getMemoryAddress(), slabs[0].getSize());
     fragment.getNextBlock();
     fail("getNextBlock failed to throw UnsupportedOperationException");
@@ -271,7 +230,6 @@ public class FragmentJUnitTest {
   public void getSlabIdThrowsExceptionForFragment() {
     expectedException.expect(UnsupportedOperationException.class);
 
-    slabs = allocateMemorySlabs();
     Fragment fragment = new Fragment(slabs[0].getMemoryAddress(), slabs[0].getSize());
     fragment.getSlabId();
     fail("getSlabId failed to throw UnsupportedOperationException");

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9899940b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/FreeListManagerTest.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/FreeListManagerTest.java b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/FreeListManagerTest.java
new file mode 100644
index 0000000..64032cc
--- /dev/null
+++ b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/FreeListManagerTest.java
@@ -0,0 +1,797 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.gemstone.gemfire.internal.offheap;
+
+import static org.junit.Assert.*;
+import static org.mockito.Mockito.*;
+import static com.googlecode.catchexception.CatchException.*;
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicReferenceArray;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+import com.gemstone.gemfire.LogWriter;
+import com.gemstone.gemfire.OutOfOffHeapMemoryException;
+import com.gemstone.gemfire.test.junit.categories.UnitTest;
+
+@Category(UnitTest.class)
+public class FreeListManagerTest {
+  static {
+    ClassLoader.getSystemClassLoader().setDefaultAssertionStatus(true);
+  }
+
+  private final int DEFAULT_SLAB_SIZE = 1024*1024*5;
+  private final SimpleMemoryAllocatorImpl ma = mock(SimpleMemoryAllocatorImpl.class);
+  private final OffHeapMemoryStats stats = mock(OffHeapMemoryStats.class);
+  private TestableFreeListManager freeListManager;
+  
+
+  @BeforeClass
+  public static void setUpBeforeClass() throws Exception {
+  }
+
+  @AfterClass
+  public static void tearDownAfterClass() throws Exception {
+  }
+
+  @Before
+  public void setUp() throws Exception {
+    when(ma.getStats()).thenReturn(stats);
+  }
+
+  @After
+  public void tearDown() throws Exception {
+    if (this.freeListManager != null) {
+      this.freeListManager.freeSlabs();
+    }
+  }
+  
+  private static TestableFreeListManager createFreeListManager(SimpleMemoryAllocatorImpl ma, AddressableMemoryChunk[] slabs) {
+    return new TestableFreeListManager(ma, slabs);
+  }
+  
+  private void setUpSingleSlabManager() {
+    setUpSingleSlabManager(DEFAULT_SLAB_SIZE);
+  }
+  private void setUpSingleSlabManager(int slabSize) {
+    UnsafeMemoryChunk slab = new UnsafeMemoryChunk(slabSize);
+    this.freeListManager = createFreeListManager(ma, new UnsafeMemoryChunk[] {slab});
+  }
+
+  @Test
+  public void usedMemoryIsZeroOnDefault() {
+    setUpSingleSlabManager();
+    assertThat(this.freeListManager.getUsedMemory()).isZero();
+  }
+
+  @Test
+  public void freeMemoryIsSlabSizeOnDefault() {
+    setUpSingleSlabManager();
+    assertThat(this.freeListManager.getFreeMemory()).isEqualTo(DEFAULT_SLAB_SIZE);
+  }
+  
+  @Test
+  public void totalMemoryIsSlabSizeOnDefault() {
+    setUpSingleSlabManager();
+    assertThat(this.freeListManager.getTotalMemory()).isEqualTo(DEFAULT_SLAB_SIZE);
+  }
+  
+  @Test
+  public void allocateTinyChunkHasCorrectSize() {
+    setUpSingleSlabManager();
+    int tinySize = 10;
+
+    ObjectChunk c = this.freeListManager.allocate(tinySize);
+    
+    validateChunkSizes(c, tinySize);
+  }
+  
+  private void validateChunkSizes(ObjectChunk c, int dataSize) {
+    assertThat(c).isNotNull();
+    assertThat(c.getDataSize()).isEqualTo(dataSize);
+    assertThat(c.getSize()).isEqualTo(computeExpectedSize(dataSize));
+  }
+
+  @Test
+  public void allocateTinyChunkFromFreeListHasCorrectSize() {
+    setUpSingleSlabManager();
+    int tinySize = 10;
+    
+    ObjectChunk c = this.freeListManager.allocate(tinySize);
+    ObjectChunk.release(c.getMemoryAddress(), this.freeListManager);
+    c = this.freeListManager.allocate(tinySize);
+
+    validateChunkSizes(c, tinySize);
+  }
+  
+  @Test
+  public void allocateTinyChunkFromEmptyFreeListHasCorrectSize() {
+    setUpSingleSlabManager();
+    int dataSize = 10;
+    
+    ObjectChunk c = this.freeListManager.allocate(dataSize);
+    ObjectChunk.release(c.getMemoryAddress(), this.freeListManager);
+    this.freeListManager.allocate(dataSize);
+    // free list will now be empty
+    c = this.freeListManager.allocate(dataSize);
+
+    validateChunkSizes(c, dataSize);
+  }
+
+  @Test
+  public void allocateHugeChunkHasCorrectSize() {
+    setUpSingleSlabManager();
+    int hugeSize = FreeListManager.MAX_TINY+1;
+
+    ObjectChunk c = this.freeListManager.allocate(hugeSize);
+
+    validateChunkSizes(c, hugeSize);
+  }
+  
+  @Test
+  public void allocateHugeChunkFromEmptyFreeListHasCorrectSize() {
+    setUpSingleSlabManager();
+    int dataSize = FreeListManager.MAX_TINY+1;
+    
+    ObjectChunk c = this.freeListManager.allocate(dataSize);
+    ObjectChunk.release(c.getMemoryAddress(), this.freeListManager);
+    this.freeListManager.allocate(dataSize);
+    // free list will now be empty
+    c = this.freeListManager.allocate(dataSize);
+    
+    validateChunkSizes(c, dataSize);
+  }
+
+  @Test
+  public void allocateHugeChunkFromFragmentWithItemInFreeListHasCorrectSize() {
+    setUpSingleSlabManager();
+    int dataSize = FreeListManager.MAX_TINY+1+1024;
+    
+    ObjectChunk c = this.freeListManager.allocate(dataSize);
+    ObjectChunk.release(c.getMemoryAddress(), this.freeListManager);
+    dataSize = FreeListManager.MAX_TINY+1;
+    c = this.freeListManager.allocate(dataSize);
+    
+    validateChunkSizes(c, dataSize);
+  }
+  @Test
+  public void freeTinyMemoryDefault() {
+    setUpSingleSlabManager();
+    
+    assertThat(this.freeListManager.getFreeTinyMemory()).isZero();
+  }
+  @Test
+  public void freeTinyMemoryEqualToChunkSize() {
+    setUpSingleSlabManager();
+    int dataSize = 10;
+    
+    ObjectChunk c = this.freeListManager.allocate(dataSize);
+    ObjectChunk.release(c.getMemoryAddress(), this.freeListManager);
+    
+    assertThat(this.freeListManager.getFreeTinyMemory()).isEqualTo(computeExpectedSize(dataSize));
+  }
+   
+  @Test
+  public void freeTinyMemoryWithTwoTinyFreeListsEqualToChunkSize() {
+    setUpSingleSlabManager();
+    int dataSize = 10;
+    
+    ObjectChunk c = this.freeListManager.allocate(dataSize);
+    ObjectChunk.release(c.getMemoryAddress(), this.freeListManager);
+    
+    int dataSize2 = 100;
+    
+    ObjectChunk c2 = this.freeListManager.allocate(dataSize2);
+    ObjectChunk.release(c2.getMemoryAddress(), this.freeListManager);
+    
+    assertThat(this.freeListManager.getFreeTinyMemory()).isEqualTo(computeExpectedSize(dataSize)+computeExpectedSize(dataSize2));
+  }
+   
+  @Test
+  public void freeHugeMemoryDefault() {
+    setUpSingleSlabManager();
+    
+    assertThat(this.freeListManager.getFreeHugeMemory()).isZero();
+  }
+  @Test
+  public void freeHugeMemoryEqualToChunkSize() {
+    setUpSingleSlabManager();
+    int dataSize = FreeListManager.MAX_TINY+1+1024;
+    
+    ObjectChunk c = this.freeListManager.allocate(dataSize);
+    ObjectChunk.release(c.getMemoryAddress(), this.freeListManager);
+    
+    assertThat(this.freeListManager.getFreeHugeMemory()).isEqualTo(computeExpectedSize(dataSize));
+  }
+  
+  @Test
+  public void freeFragmentMemoryDefault() {
+    setUpSingleSlabManager();
+    
+    assertThat(this.freeListManager.getFreeFragmentMemory()).isEqualTo(DEFAULT_SLAB_SIZE);
+  }
+  
+  @Test
+  public void freeFragmentMemorySomeOfFragmentAllocated() {
+    setUpSingleSlabManager();
+    ObjectChunk c = this.freeListManager.allocate(DEFAULT_SLAB_SIZE/4-8);
+    
+    assertThat(this.freeListManager.getFreeFragmentMemory()).isEqualTo((DEFAULT_SLAB_SIZE/4)*3);
+  }
+  
+  @Test
+  public void freeFragmentMemoryMostOfFragmentAllocated() {
+    setUpSingleSlabManager();
+    ObjectChunk c = this.freeListManager.allocate(DEFAULT_SLAB_SIZE-8-8);
+    
+    assertThat(this.freeListManager.getFreeFragmentMemory()).isZero();
+  }
+  
+  private int computeExpectedSize(int dataSize) {
+    return ((dataSize + ObjectChunk.OFF_HEAP_HEADER_SIZE + 7) / 8) * 8;
+  }
+
+  @Test(expected = AssertionError.class)
+  public void allocateZeroThrowsAssertion() {
+    setUpSingleSlabManager();
+    this.freeListManager.allocate(0);
+  }
+  
+  @Test
+  public void allocateFromMultipleSlabs() {
+    int SMALL_SLAB = 16;
+    int MEDIUM_SLAB = 128;
+    UnsafeMemoryChunk slab = new UnsafeMemoryChunk(DEFAULT_SLAB_SIZE);
+    this.freeListManager = createFreeListManager(ma, new UnsafeMemoryChunk[] {
+        new UnsafeMemoryChunk(SMALL_SLAB), 
+        new UnsafeMemoryChunk(SMALL_SLAB), 
+        new UnsafeMemoryChunk(MEDIUM_SLAB), 
+        slab});
+    this.freeListManager.allocate(SMALL_SLAB-8+1);
+    this.freeListManager.allocate(DEFAULT_SLAB_SIZE-8);
+    this.freeListManager.allocate(SMALL_SLAB-8+1);
+    assertThat(this.freeListManager.getFreeMemory()).isEqualTo(SMALL_SLAB*2+MEDIUM_SLAB-((SMALL_SLAB+8)*2));
+    assertThat(this.freeListManager.getUsedMemory()).isEqualTo(DEFAULT_SLAB_SIZE+(SMALL_SLAB+8)*2);
+    assertThat(this.freeListManager.getTotalMemory()).isEqualTo(DEFAULT_SLAB_SIZE+MEDIUM_SLAB+SMALL_SLAB*2);
+  }
+  
+  @Test
+  public void compactWithLargeChunkSizeReturnsFalse() {
+    int SMALL_SLAB = 16;
+    int MEDIUM_SLAB = 128;
+    UnsafeMemoryChunk slab = new UnsafeMemoryChunk(DEFAULT_SLAB_SIZE);
+    this.freeListManager = createFreeListManager(ma, new UnsafeMemoryChunk[] {
+        new UnsafeMemoryChunk(SMALL_SLAB), 
+        new UnsafeMemoryChunk(SMALL_SLAB), 
+        new UnsafeMemoryChunk(MEDIUM_SLAB), 
+        slab});
+    ArrayList<ObjectChunk> chunks = new ArrayList<>();
+    chunks.add(this.freeListManager.allocate(SMALL_SLAB-8+1));
+    chunks.add(this.freeListManager.allocate(DEFAULT_SLAB_SIZE/2-8));
+    chunks.add(this.freeListManager.allocate(DEFAULT_SLAB_SIZE/2-8));
+    chunks.add(this.freeListManager.allocate(SMALL_SLAB-8+1));
+    for (ObjectChunk c: chunks) {
+      ObjectChunk.release(c.getMemoryAddress(), this.freeListManager);
+    }
+    this.freeListManager.firstCompact = false;
+    assertThat(this.freeListManager.compact(DEFAULT_SLAB_SIZE+1)).isFalse();
+  }
+  
+  @Test
+  public void compactWithChunkSizeOfMaxSlabReturnsTrue() {
+    int SMALL_SLAB = 16;
+    int MEDIUM_SLAB = 128;
+    UnsafeMemoryChunk slab = new UnsafeMemoryChunk(DEFAULT_SLAB_SIZE);
+    this.freeListManager = createFreeListManager(ma, new UnsafeMemoryChunk[] {
+        new UnsafeMemoryChunk(SMALL_SLAB), 
+        new UnsafeMemoryChunk(SMALL_SLAB), 
+        new UnsafeMemoryChunk(MEDIUM_SLAB), 
+        slab});
+    ArrayList<ObjectChunk> chunks = new ArrayList<>();
+    chunks.add(this.freeListManager.allocate(SMALL_SLAB-8+1));
+    chunks.add(this.freeListManager.allocate(DEFAULT_SLAB_SIZE/2-8));
+    chunks.add(this.freeListManager.allocate(DEFAULT_SLAB_SIZE/2-8));
+    chunks.add(this.freeListManager.allocate(SMALL_SLAB-8+1));
+    for (ObjectChunk c: chunks) {
+      ObjectChunk.release(c.getMemoryAddress(), this.freeListManager);
+    }
+    
+    assertThat(this.freeListManager.compact(DEFAULT_SLAB_SIZE)).isTrue();
+    //assertThat(this.freeListManager.getFragmentList()).hasSize(4); // TODO intermittently fails because Fragments may be merged
+  }
+  
+  @Test
+  public void compactWithLiveChunks() {
+    int SMALL_SLAB = 16;
+    int MEDIUM_SLAB = 128;
+    UnsafeMemoryChunk slab = new UnsafeMemoryChunk(DEFAULT_SLAB_SIZE);
+    this.freeListManager = createFreeListManager(ma, new UnsafeMemoryChunk[] {
+        new UnsafeMemoryChunk(SMALL_SLAB), 
+        new UnsafeMemoryChunk(SMALL_SLAB), 
+        new UnsafeMemoryChunk(MEDIUM_SLAB), 
+        slab});
+    ArrayList<ObjectChunk> chunks = new ArrayList<>();
+    chunks.add(this.freeListManager.allocate(SMALL_SLAB-8+1));
+    this.freeListManager.allocate(DEFAULT_SLAB_SIZE/2-8);
+    chunks.add(this.freeListManager.allocate(DEFAULT_SLAB_SIZE/2-8));
+    this.freeListManager.allocate(SMALL_SLAB-8+1);
+    for (ObjectChunk c: chunks) {
+      ObjectChunk.release(c.getMemoryAddress(), this.freeListManager);
+    }
+    
+    assertThat(this.freeListManager.compact(DEFAULT_SLAB_SIZE/2)).isTrue();
+  }
+  
+  @Test
+  public void compactAfterAllocatingAll() {
+    setUpSingleSlabManager();
+    ObjectChunk c = freeListManager.allocate(DEFAULT_SLAB_SIZE-8);
+    this.freeListManager.firstCompact = false;
+    assertThat(this.freeListManager.compact(1)).isFalse();
+    // call compact twice for extra code coverage
+    assertThat(this.freeListManager.compact(1)).isFalse();
+    assertThat(this.freeListManager.getFragmentList()).isEmpty();
+  }
+  
+  @Test
+  public void afterAllocatingAllOneSizeCompactToAllocateDifferentSize() {
+    setUpSingleSlabManager();
+    ArrayList<ObjectChunk> chunksToFree = new ArrayList<>();
+    ArrayList<ObjectChunk> chunksToFreeLater = new ArrayList<>();
+    int ALLOCATE_COUNT = 1000;
+    ObjectChunk bigChunk = freeListManager.allocate(DEFAULT_SLAB_SIZE-8-(ALLOCATE_COUNT*32)-256-256);
+    for (int i=0; i < ALLOCATE_COUNT; i++) {
+      ObjectChunk c = freeListManager.allocate(24);
+      if (i%3 != 2) {
+        chunksToFree.add(c);
+      } else {
+        chunksToFreeLater.add(c);
+      }
+    }
+    ObjectChunk c1 = freeListManager.allocate(64-8);
+    ObjectChunk c2 = freeListManager.allocate(64-8);
+    ObjectChunk c3 = freeListManager.allocate(64-8);
+    ObjectChunk c4 = freeListManager.allocate(64-8);
+
+    ObjectChunk mediumChunk1 = freeListManager.allocate(128-8);
+    ObjectChunk mediumChunk2 = freeListManager.allocate(128-8);
+
+    ObjectChunk.release(bigChunk.getMemoryAddress(), freeListManager);
+    int s = chunksToFree.size();
+    for (int i=s/2; i >=0; i--) {
+      ObjectChunk c = chunksToFree.get(i);
+      ObjectChunk.release(c.getMemoryAddress(), freeListManager);
+    }
+    for (int i=(s/2)+1; i < s; i++) {
+      ObjectChunk c = chunksToFree.get(i);
+      ObjectChunk.release(c.getMemoryAddress(), freeListManager);
+    }
+    ObjectChunk.release(c3.getMemoryAddress(), freeListManager);
+    ObjectChunk.release(c1.getMemoryAddress(), freeListManager);
+    ObjectChunk.release(c2.getMemoryAddress(), freeListManager);
+    ObjectChunk.release(c4.getMemoryAddress(), freeListManager);
+    ObjectChunk.release(mediumChunk1.getMemoryAddress(), freeListManager);
+    ObjectChunk.release(mediumChunk2.getMemoryAddress(), freeListManager);
+    this.freeListManager.firstCompact = false;
+    assertThat(freeListManager.compact(DEFAULT_SLAB_SIZE-(ALLOCATE_COUNT*32))).isFalse();
+    for (int i=0; i < ((256*2)/96); i++) {
+      ObjectChunk.release(chunksToFreeLater.get(i).getMemoryAddress(), freeListManager);
+    }
+    assertThat(freeListManager.compact(DEFAULT_SLAB_SIZE-(ALLOCATE_COUNT*32))).isTrue();
+  }
+  
+  @Test
+  public void afterAllocatingAndFreeingCompact() {
+    int slabSize = 1024*3;
+    setUpSingleSlabManager(slabSize);
+    ObjectChunk bigChunk1 = freeListManager.allocate(slabSize/3-8);
+    ObjectChunk bigChunk2 = freeListManager.allocate(slabSize/3-8);
+    ObjectChunk bigChunk3 = freeListManager.allocate(slabSize/3-8);
+    this.freeListManager.firstCompact = false;
+    assertThat(freeListManager.compact(1)).isFalse();
+    ObjectChunk.release(bigChunk3.getMemoryAddress(), freeListManager);
+    ObjectChunk.release(bigChunk2.getMemoryAddress(), freeListManager);
+    ObjectChunk.release(bigChunk1.getMemoryAddress(), freeListManager);
+    assertThat(freeListManager.compact(slabSize)).isTrue();
+  }
+  
+  @Test
+  public void compactWithEmptyTinyFreeList() {
+    setUpSingleSlabManager();
+    Fragment originalFragment = this.freeListManager.getFragmentList().get(0);
+    ObjectChunk c = freeListManager.allocate(16);
+    ObjectChunk.release(c.getMemoryAddress(), this.freeListManager);
+    c = freeListManager.allocate(16);
+    this.freeListManager.firstCompact = false;
+    assertThat(this.freeListManager.compact(1)).isTrue();
+    assertThat(this.freeListManager.getFragmentList()).hasSize(1);
+    Fragment compactedFragment = this.freeListManager.getFragmentList().get(0);
+    assertThat(compactedFragment.getSize()).isEqualTo(originalFragment.getSize()-(16+8));
+    assertThat(compactedFragment.getMemoryAddress()).isEqualTo(originalFragment.getMemoryAddress()+(16+8));
+  }
+  
+  @Test
+  public void allocationsThatLeaveLessThanMinChunkSizeFreeInAFragment() {
+    int SMALL_SLAB = 16;
+    int MEDIUM_SLAB = 128;
+    UnsafeMemoryChunk slab = new UnsafeMemoryChunk(DEFAULT_SLAB_SIZE);
+    this.freeListManager = createFreeListManager(ma, new UnsafeMemoryChunk[] {
+        new UnsafeMemoryChunk(SMALL_SLAB), 
+        new UnsafeMemoryChunk(SMALL_SLAB), 
+        new UnsafeMemoryChunk(MEDIUM_SLAB), 
+        slab});
+    this.freeListManager.allocate(DEFAULT_SLAB_SIZE-8-(ObjectChunk.MIN_CHUNK_SIZE-1));
+    this.freeListManager.allocate(MEDIUM_SLAB-8-(ObjectChunk.MIN_CHUNK_SIZE-1));
+    
+    assertThat(this.freeListManager.compact(SMALL_SLAB)).isTrue();
+  }
+ @Test
+  public void maxAllocationUsesAllMemory() {
+    setUpSingleSlabManager();
+
+    this.freeListManager.allocate(DEFAULT_SLAB_SIZE-8);
+
+    assertThat(this.freeListManager.getFreeMemory()).isZero();
+    assertThat(this.freeListManager.getUsedMemory()).isEqualTo(DEFAULT_SLAB_SIZE);
+  }
+
+
+  @Test
+  public void overMaxAllocationFails() {
+    setUpSingleSlabManager();
+    OutOfOffHeapMemoryListener ooohml = mock(OutOfOffHeapMemoryListener.class);
+    when(this.ma.getOutOfOffHeapMemoryListener()).thenReturn(ooohml);
+
+    catchException(this.freeListManager).allocate(DEFAULT_SLAB_SIZE-7);
+
+    verify(ooohml).outOfOffHeapMemory(caughtException());
+  }
+  
+  @Test(expected = AssertionError.class)
+  public void allocateNegativeThrowsAssertion() {
+    setUpSingleSlabManager();
+    this.freeListManager.allocate(-123);
+  }
+  
+  @Test
+  public void hugeMultipleLessThanZeroIsIllegal() {
+    try {
+      FreeListManager.verifyHugeMultiple(-1);
+      fail("expected IllegalStateException");
+    } catch (IllegalStateException expected) {
+      assertThat(expected.getMessage()).contains("HUGE_MULTIPLE must be >= 0 and <= " + FreeListManager.HUGE_MULTIPLE + " but it was -1");
+    }
+  }
+  @Test
+  public void hugeMultipleGreaterThan256IsIllegal() {
+    try {
+      FreeListManager.verifyHugeMultiple(257);
+      fail("expected IllegalStateException");
+    } catch (IllegalStateException expected) {
+      assertThat(expected.getMessage()).contains("HUGE_MULTIPLE must be >= 0 and <= 256 but it was 257");
+    }
+  }
+  @Test
+  public void hugeMultipleof256IsLegal() {
+    FreeListManager.verifyHugeMultiple(256);
+  }
+  
+  @Test
+  public void offHeapFreeListCountLessThanZeroIsIllegal() {
+    try {
+      FreeListManager.verifyOffHeapFreeListCount(-1);
+      fail("expected IllegalStateException");
+    } catch (IllegalStateException expected) {
+      assertThat(expected.getMessage()).contains("gemfire.OFF_HEAP_FREE_LIST_COUNT must be >= 1.");
+    }
+  }
+  @Test
+  public void offHeapFreeListCountOfZeroIsIllegal() {
+    try {
+      FreeListManager.verifyOffHeapFreeListCount(0);
+      fail("expected IllegalStateException");
+    } catch (IllegalStateException expected) {
+      assertThat(expected.getMessage()).contains("gemfire.OFF_HEAP_FREE_LIST_COUNT must be >= 1.");
+    }
+  }
+  @Test
+  public void offHeapFreeListCountOfOneIsLegal() {
+    FreeListManager.verifyOffHeapFreeListCount(1);
+  }
+  @Test
+  public void offHeapAlignmentLessThanZeroIsIllegal() {
+    try {
+      FreeListManager.verifyOffHeapAlignment(-1);
+      fail("expected IllegalStateException");
+    } catch (IllegalStateException expected) {
+      assertThat(expected.getMessage()).contains("gemfire.OFF_HEAP_ALIGNMENT must be a multiple of 8");
+    }
+  }
+  @Test
+  public void offHeapAlignmentNotAMultipleOf8IsIllegal() {
+    try {
+      FreeListManager.verifyOffHeapAlignment(9);
+      fail("expected IllegalStateException");
+    } catch (IllegalStateException expected) {
+      assertThat(expected.getMessage()).contains("gemfire.OFF_HEAP_ALIGNMENT must be a multiple of 8");
+    }
+  }
+  @Test
+  public void offHeapAlignmentGreaterThan256IsIllegal() {
+    try {
+      FreeListManager.verifyOffHeapAlignment(256+8);
+      fail("expected IllegalStateException");
+    } catch (IllegalStateException expected) {
+      assertThat(expected.getMessage()).contains("gemfire.OFF_HEAP_ALIGNMENT must be <= 256");
+    }
+  }
+  @Test
+  public void offHeapAlignmentOf256IsLegal() {
+    FreeListManager.verifyOffHeapAlignment(256);
+  }
+  
+  @Test
+  public void okToReuseNull() {
+    setUpSingleSlabManager();
+    assertThat(this.freeListManager.okToReuse(null)).isTrue();
+  }
+  
+  @Test
+  public void okToReuseSameSlabs() {
+    UnsafeMemoryChunk slab = new UnsafeMemoryChunk(DEFAULT_SLAB_SIZE);
+    UnsafeMemoryChunk[] slabs = new UnsafeMemoryChunk[] {slab};
+    this.freeListManager = createFreeListManager(ma, slabs);
+    assertThat(this.freeListManager.okToReuse(slabs)).isTrue();
+  }
+  @Test
+  public void notOkToReuseDifferentSlabs() {
+    UnsafeMemoryChunk slab = new UnsafeMemoryChunk(DEFAULT_SLAB_SIZE);
+    UnsafeMemoryChunk[] slabs = new UnsafeMemoryChunk[] {slab};
+    this.freeListManager = createFreeListManager(ma, slabs);
+    UnsafeMemoryChunk[] slabs2 = new UnsafeMemoryChunk[] {slab};
+    assertThat(this.freeListManager.okToReuse(slabs2)).isFalse();
+  }
+  @Test
+  public void firstSlabAlwaysLargest() {
+    this.freeListManager = createFreeListManager(ma, new UnsafeMemoryChunk[] {
+        new UnsafeMemoryChunk(10), 
+        new UnsafeMemoryChunk(100)});
+    assertThat(this.freeListManager.getLargestSlabSize()).isEqualTo(10);
+  }
+
+  @Test
+  public void findSlab() {
+    UnsafeMemoryChunk chunk = new UnsafeMemoryChunk(10);
+    long address = chunk.getMemoryAddress();
+    this.freeListManager = createFreeListManager(ma, new UnsafeMemoryChunk[] {chunk});
+    assertThat(this.freeListManager.findSlab(address)).isEqualTo(0);
+    assertThat(this.freeListManager.findSlab(address+9)).isEqualTo(0);
+    catchException(this.freeListManager).findSlab(address-1);
+    assertThat((Exception)caughtException())
+    .isExactlyInstanceOf(IllegalStateException.class)
+    .hasMessage("could not find a slab for addr " + (address-1));
+    catchException(this.freeListManager).findSlab(address+10);
+    assertThat((Exception)caughtException())
+    .isExactlyInstanceOf(IllegalStateException.class)
+    .hasMessage("could not find a slab for addr " + (address+10));
+  }
+  
+  @Test
+  public void findSecondSlab() {
+    UnsafeMemoryChunk chunk = new UnsafeMemoryChunk(10);
+    long address = chunk.getMemoryAddress();
+    UnsafeMemoryChunk slab = new UnsafeMemoryChunk(DEFAULT_SLAB_SIZE);
+    this.freeListManager = createFreeListManager(ma, new UnsafeMemoryChunk[] {slab, chunk});
+    assertThat(this.freeListManager.findSlab(address)).isEqualTo(1);
+    assertThat(this.freeListManager.findSlab(address+9)).isEqualTo(1);
+    catchException(this.freeListManager).findSlab(address-1);
+    assertThat((Exception)caughtException())
+    .isExactlyInstanceOf(IllegalStateException.class)
+    .hasMessage("could not find a slab for addr " + (address-1));
+    catchException(this.freeListManager).findSlab(address+10);
+    assertThat((Exception)caughtException())
+    .isExactlyInstanceOf(IllegalStateException.class)
+    .hasMessage("could not find a slab for addr " + (address+10));
+  }
+  
+  @Test
+  public void validateAddressWithinSlab() {
+    UnsafeMemoryChunk chunk = new UnsafeMemoryChunk(10);
+    long address = chunk.getMemoryAddress();
+    this.freeListManager = createFreeListManager(ma, new UnsafeMemoryChunk[] {chunk});
+    assertThat(this.freeListManager.validateAddressAndSizeWithinSlab(address, -1)).isTrue();
+    assertThat(this.freeListManager.validateAddressAndSizeWithinSlab(address+9, -1)).isTrue();
+    assertThat(this.freeListManager.validateAddressAndSizeWithinSlab(address-1, -1)).isFalse();
+    assertThat(this.freeListManager.validateAddressAndSizeWithinSlab(address+10, -1)).isFalse();
+  }
+  
+  @Test
+  public void validateAddressAndSizeWithinSlab() {
+    UnsafeMemoryChunk chunk = new UnsafeMemoryChunk(10);
+    long address = chunk.getMemoryAddress();
+    this.freeListManager = createFreeListManager(ma, new UnsafeMemoryChunk[] {chunk});
+    assertThat(this.freeListManager.validateAddressAndSizeWithinSlab(address, 1)).isTrue();
+    assertThat(this.freeListManager.validateAddressAndSizeWithinSlab(address, 10)).isTrue();
+    catchException(this.freeListManager).validateAddressAndSizeWithinSlab(address, 0);
+    assertThat((Exception)caughtException())
+    .isExactlyInstanceOf(IllegalStateException.class)
+    .hasMessage(" address 0x" + Long.toString(address+0-1, 16) + " does not address the original slab memory");
+    catchException(this.freeListManager).validateAddressAndSizeWithinSlab(address, 11);
+    assertThat((Exception)caughtException())
+    .isExactlyInstanceOf(IllegalStateException.class)
+    .hasMessage(" address 0x" + Long.toString(address+11-1, 16) + " does not address the original slab memory");
+  }
+  
+  @Test
+  public void descriptionOfOneSlab() {
+    UnsafeMemoryChunk chunk = new UnsafeMemoryChunk(10);
+    long address = chunk.getMemoryAddress();
+    long endAddress = address+10;
+    this.freeListManager = createFreeListManager(ma, new UnsafeMemoryChunk[] {chunk});
+    StringBuilder sb = new StringBuilder();
+    this.freeListManager.getSlabDescriptions(sb);
+    assertThat(sb.toString()).isEqualTo("[" + Long.toString(address, 16) + ".." + Long.toString(endAddress, 16) + "] ");
+  }
+
+  @Test
+  public void orderBlocksContainsFragment() {
+    UnsafeMemoryChunk chunk = new UnsafeMemoryChunk(10);
+    long address = chunk.getMemoryAddress();
+    this.freeListManager = createFreeListManager(ma, new UnsafeMemoryChunk[] {chunk});
+    List<MemoryBlock> ob = this.freeListManager.getOrderedBlocks();
+    assertThat(ob).hasSize(1);
+    assertThat(ob.get(0).getMemoryAddress()).isEqualTo(address);
+    assertThat(ob.get(0).getBlockSize()).isEqualTo(10);
+  }
+  
+  @Test
+  public void orderBlocksContainsTinyFree() {
+    UnsafeMemoryChunk chunk = new UnsafeMemoryChunk(96);
+    long address = chunk.getMemoryAddress();
+    this.freeListManager = createFreeListManager(ma, new UnsafeMemoryChunk[] {chunk});
+    ObjectChunk c = this.freeListManager.allocate(24);
+    ObjectChunk c2 = this.freeListManager.allocate(24);
+    ObjectChunk.release(c.getMemoryAddress(), this.freeListManager);
+
+    List<MemoryBlock> ob = this.freeListManager.getOrderedBlocks();
+    assertThat(ob).hasSize(3);
+  }
+
+  @Test
+  public void allocatedBlocksEmptyIfNoAllocations() {
+    UnsafeMemoryChunk chunk = new UnsafeMemoryChunk(10);
+    this.freeListManager = createFreeListManager(ma, new UnsafeMemoryChunk[] {chunk});
+    List<MemoryBlock> ob = this.freeListManager.getAllocatedBlocks();
+    assertThat(ob).hasSize(0);
+  }
+
+  @Test
+  public void allocatedBlocksEmptyAfterFree() {
+    UnsafeMemoryChunk chunk = new UnsafeMemoryChunk(96);
+    this.freeListManager = createFreeListManager(ma, new UnsafeMemoryChunk[] {chunk});
+    ObjectChunk c = this.freeListManager.allocate(24);
+    ObjectChunk.release(c.getMemoryAddress(), this.freeListManager);
+    List<MemoryBlock> ob = this.freeListManager.getAllocatedBlocks();
+    assertThat(ob).hasSize(0);
+  }
+
+  @Test
+  public void allocatedBlocksHasAllocatedChunk() {
+    UnsafeMemoryChunk chunk = new UnsafeMemoryChunk(96);
+    this.freeListManager = createFreeListManager(ma, new UnsafeMemoryChunk[] {chunk});
+    ObjectChunk c = this.freeListManager.allocate(24);
+    List<MemoryBlock> ob = this.freeListManager.getAllocatedBlocks();
+    assertThat(ob).hasSize(1);
+    assertThat(ob.get(0).getMemoryAddress()).isEqualTo(c.getMemoryAddress());
+  }
+  
+  @Test
+  public void allocatedBlocksHasBothAllocatedChunks() {
+    UnsafeMemoryChunk chunk = new UnsafeMemoryChunk(96);
+    this.freeListManager = createFreeListManager(ma, new UnsafeMemoryChunk[] {chunk});
+    ObjectChunk c = this.freeListManager.allocate(24);
+    ObjectChunk c2 = this.freeListManager.allocate(33);
+    List<MemoryBlock> ob = this.freeListManager.getAllocatedBlocks();
+    assertThat(ob).hasSize(2);
+  }
+  
+  @Test
+  public void allocateFromFragmentWithBadIndexesReturnsNull() {
+    UnsafeMemoryChunk chunk = new UnsafeMemoryChunk(96);
+    this.freeListManager = createFreeListManager(ma, new UnsafeMemoryChunk[] {chunk});
+    assertThat(this.freeListManager.allocateFromFragment(-1, 32)).isNull();
+    assertThat(this.freeListManager.allocateFromFragment(1, 32)).isNull();
+  }
+
+  @Test
+  public void testLogging() {
+    UnsafeMemoryChunk chunk = new UnsafeMemoryChunk(32);
+    UnsafeMemoryChunk chunk2 = new UnsafeMemoryChunk(1024*1024*5);
+    this.freeListManager = createFreeListManager(ma, new UnsafeMemoryChunk[] {chunk, chunk2});
+    ObjectChunk c = this.freeListManager.allocate(24);
+    ObjectChunk c2 = this.freeListManager.allocate(1024*1024);
+    ObjectChunk.release(c.getMemoryAddress(), this.freeListManager);
+    ObjectChunk.release(c2.getMemoryAddress(), this.freeListManager);
+    
+    LogWriter lw = mock(LogWriter.class);
+    this.freeListManager.logOffHeapState(lw, 1024);
+  }
+  /**
+   * Just like Fragment except that the first time allocate is called
+   * it returns false indicating that the allocate failed.
+   * In a real system this would only happen if a concurrent allocate
+   * happened. This allows better code coverage.
+   */
+  private static class TestableFragment extends Fragment {
+    private boolean allocateCalled = false;
+    public TestableFragment(long addr, int size) {
+      super(addr, size);
+    }
+    @Override
+    public boolean allocate(int oldOffset, int newOffset) {
+      if (!allocateCalled) {
+        allocateCalled = true;
+        return false;
+      }
+      return super.allocate(oldOffset, newOffset);
+    }
+  }
+  private static class TestableFreeListManager extends FreeListManager {
+    private boolean firstTime = true;
+    
+    @Override
+    protected Fragment createFragment(long addr, int size) {
+      return new TestableFragment(addr, size);
+    }
+
+    @Override
+    protected SyncChunkStack createFreeListForEmptySlot(AtomicReferenceArray<SyncChunkStack> freeLists, int idx) {
+      if (this.firstTime) {
+        this.firstTime = false;
+        SyncChunkStack clq = super.createFreeListForEmptySlot(freeLists, idx);
+        if (!freeLists.compareAndSet(idx, null, clq)) {
+          fail("this should never happen. Indicates a concurrent modification");
+        }
+      }
+      return super.createFreeListForEmptySlot(freeLists, idx);
+    }
+
+    public boolean firstCompact = true;
+    @Override
+    protected void afterCompactCountFetched() {
+      if (this.firstCompact) {
+        this.firstCompact = false;
+        // Force compact into thinking a concurrent compaction happened.
+        this.compactCount.incrementAndGet();
+      }
+    }
+    
+    public TestableFreeListManager(SimpleMemoryAllocatorImpl ma, AddressableMemoryChunk[] slabs) {
+      super(ma, slabs);
+    }
+    
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9899940b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/FreeListOffHeapRegionJUnitTest.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/FreeListOffHeapRegionJUnitTest.java b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/FreeListOffHeapRegionJUnitTest.java
index 93f2039..6790f6a 100644
--- a/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/FreeListOffHeapRegionJUnitTest.java
+++ b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/FreeListOffHeapRegionJUnitTest.java
@@ -40,7 +40,7 @@ public class FreeListOffHeapRegionJUnitTest extends OffHeapRegionBase {
 
   @Override
   public int perObjectOverhead() {
-    return Chunk.OFF_HEAP_HEADER_SIZE;
+    return ObjectChunk.OFF_HEAP_HEADER_SIZE;
   }
 
 }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9899940b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/GemFireChunkFactoryJUnitTest.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/GemFireChunkFactoryJUnitTest.java b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/GemFireChunkFactoryJUnitTest.java
deleted file mode 100644
index d12b823..0000000
--- a/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/GemFireChunkFactoryJUnitTest.java
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.gemstone.gemfire.internal.offheap;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.mockito.Mockito.mock;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-
-import com.gemstone.gemfire.LogWriter;
-import com.gemstone.gemfire.internal.cache.EntryEventImpl;
-import com.gemstone.gemfire.test.junit.categories.UnitTest;
-
-@Category(UnitTest.class)
-public class GemFireChunkFactoryJUnitTest {
-
-  private MemoryAllocator ma;
-
-  @Before
-  public void setUp() {
-    OutOfOffHeapMemoryListener ooohml = mock(OutOfOffHeapMemoryListener.class);
-    OffHeapMemoryStats stats = mock(OffHeapMemoryStats.class);
-    LogWriter lw = mock(LogWriter.class);
-
-    ma = SimpleMemoryAllocatorImpl.create(ooohml, stats, lw, 1, OffHeapStorage.MIN_SLAB_SIZE * 1, OffHeapStorage.MIN_SLAB_SIZE);
-  }
-
-  @After
-  public void tearDown() {
-    SimpleMemoryAllocatorImpl.freeOffHeapMemory();
-  }
-
-  private GemFireChunk createChunk(Object value) {
-    byte[] v = EntryEventImpl.serialize(value);
-
-    boolean isSerialized = true;
-    boolean isCompressed = false;
-
-    GemFireChunk chunk = (GemFireChunk) ma.allocateAndInitialize(v, isSerialized, isCompressed, GemFireChunk.TYPE);
-
-    return chunk;
-  }
-
-  @Test
-  public void factoryShouldCreateNewChunkWithGivenAddress() {
-    GemFireChunk chunk = createChunk(Long.MAX_VALUE);
-
-    ChunkFactory factory = new GemFireChunkFactory();
-    Chunk newChunk = factory.newChunk(chunk.getMemoryAddress());
-
-    assertNotNull(newChunk);
-    assertEquals(GemFireChunk.class, newChunk.getClass());
-
-    assertThat(newChunk.getMemoryAddress()).isEqualTo(chunk.getMemoryAddress());
-
-    chunk.release();
-  }
-
-  @Test
-  public void factoryShouldCreateNewChunkWithGivenAddressAndType() {
-    GemFireChunk chunk = createChunk(Long.MAX_VALUE);
-
-    ChunkFactory factory = new GemFireChunkFactory();
-    Chunk newChunk = factory.newChunk(chunk.getMemoryAddress(), GemFireChunk.TYPE);
-
-    assertNotNull(newChunk);
-    assertEquals(GemFireChunk.class, newChunk.getClass());
-
-    assertThat(newChunk.getMemoryAddress()).isEqualTo(chunk.getMemoryAddress());
-    assertThat(newChunk.getChunkType()).isEqualTo(GemFireChunk.TYPE);
-
-    chunk.release();
-  }
-
-  @Test
-  public void shouldGetChunkTypeFromAddress() {
-    byte[] v = EntryEventImpl.serialize(Long.MAX_VALUE);
-
-    boolean isSerialized = true;
-    boolean isCompressed = false;
-
-    GemFireChunk chunk = (GemFireChunk) ma.allocateAndInitialize(v, isSerialized, isCompressed, GemFireChunk.TYPE);
-
-    ChunkFactory factory = new GemFireChunkFactory();
-    ChunkType actualType = factory.getChunkTypeForAddress(chunk.getMemoryAddress());
-
-    assertEquals(GemFireChunk.TYPE, actualType);
-
-    chunk.release();
-  }
-
-  @Test
-  public void shouldGetChunkTypeFromRawBits() {
-    byte[] v = EntryEventImpl.serialize(Long.MAX_VALUE);
-
-    boolean isSerialized = true;
-    boolean isCompressed = false;
-
-    GemFireChunk chunk = (GemFireChunk) ma.allocateAndInitialize(v, isSerialized, isCompressed, GemFireChunk.TYPE);
-
-    int rawBits = UnsafeMemoryChunk.readAbsoluteIntVolatile(chunk.getMemoryAddress() + 4 /* REF_COUNT_OFFSET */);
-
-    ChunkFactory factory = new GemFireChunkFactory();
-    ChunkType actualType = factory.getChunkTypeForRawBits(rawBits);
-    assertEquals(GemFireChunk.TYPE, actualType);
-
-    chunk.release();
-  }
-}



Mime
View raw message