@Test
  public void testMemoryInspection() throws IOException {
    // validate initial state
    MemoryAllocator allocator = cache.getOffHeapStore();
    assertNotNull(allocator);
    MemoryInspector inspector = allocator.getMemoryInspector();
    assertNotNull(inspector);
    inspector.createSnapshot();
    try {
      MemoryBlock firstBlock = inspector.getFirstBlock();
      assertNotNull(firstBlock);
      assertEquals(1024 * 1024 * 2, firstBlock.getBlockSize());
      assertEquals("N/A", firstBlock.getDataType());
      assertEquals(-1, firstBlock.getFreeListId());
      assertTrue(firstBlock.getAddress() > 0);
      assertNull(firstBlock.getNextBlock());
      assertEquals(0, firstBlock.getRefCount());
      assertEquals(0, firstBlock.getSlabId());
      assertEquals(MemoryBlock.State.UNUSED, firstBlock.getState());
      assertFalse(firstBlock.isCompressed());
      assertFalse(firstBlock.isSerialized());
    } finally {
      inspector.clearSnapshot();
    }

    // create off-heap region
    Region<Object, Object> region = cache.createRegionFactory(getRegionShortcut())
        .setOffHeap(true).create(getRegionName());
    Region<Object, Object> compressedRegion = cache.createRegionFactory(getRegionShortcut())
        .setOffHeap(true).setCompressor(SnappyCompressor.getDefaultInstance())
        .create(getRegionName() + "Compressed");

    // perform some ops
    List<ExpectedValues> expected = new ArrayList<>();

    // Chunk.OFF_HEAP_HEADER_SIZE + 4 ?

    putString(region, expected);
    putCompressedString(compressedRegion, expected);
    putDate(region, expected);
    putByteArray(region, expected);
    putCompressedByteArray(compressedRegion, expected);
    putByteArrayArray(region, expected);
    putShortArray(region, expected);
    putStringArray(region, expected);
    putObjectArray(region, expected);
    putArrayList(region, expected);
    putLinkedList(region, expected);
    putHashSet(region, expected);
    putLinkedHashSet(region, expected);
    putHashMap(region, expected);
    putIdentityHashMap(region, expected);
    putHashtable(region, expected);
    putProperties(region, expected);
    putVector(region, expected);
    putStack(region, expected);
    putTreeMap(region, expected);
    putTreeSet(region, expected);
    putClass(region, expected);
    putUUID(region, expected);
    putTimestamp(region, expected);
    putSerializableClass(region, expected);

    // TODO: USER_DATA_SERIALIZABLE

    // TODO: PDX

    // TODO: PDX_ENUM

    // TODO: GEMFIRE_ENUM

    // TODO: PDX_INLINE_ENUM

    // validate inspection
    inspector.createSnapshot();
    try {
      MemoryBlock firstBlock = inspector.getFirstBlock();
      assertEquals(MemoryBlock.State.UNUSED, firstBlock.getState());

      // System.out.println(((MemoryAllocatorImpl)inspector).getSnapshot());

      // sort the ExpectedValues into the same order as the MemberBlocks from inspector
      Collections.sort(expected,
          (o1, o2) -> Long.valueOf(o1.memoryAddress).compareTo(o2.memoryAddress));

      int i = 0;
      MemoryBlock block = firstBlock.getNextBlock();
      while (block != null) {
        ExpectedValues values = expected.get(i);
        assertEquals(i + ":" + values.dataType, values.blockSize, block.getBlockSize());
        assertEquals(i + ":" + values.dataType, values.dataType, block.getDataType());
        assertEquals(i + ":" + values.dataType, values.freeListId, block.getFreeListId());
        assertEquals(i + ":" + values.dataType, values.memoryAddress, block.getAddress());
        assertEquals(i + ":" + values.dataType, values.refCount, block.getRefCount());
        assertEquals(i + ":" + values.dataType, values.slabId, block.getSlabId());
        assertEquals(i + ":" + values.dataType, values.isCompressed, block.isCompressed());
        assertEquals(i + ":" + values.dataType, values.isSerialized, block.isSerialized());
        // compare block.getDataValue() but only for String types
        if (values.dataType.equals("java.lang.String")) {
          Object obj = block.getDataValue();
          assertNotNull(block.toString(), obj);
          assertTrue(obj instanceof String);
          assertEquals("this is a string", obj);
        }
        if ((values.dataType.contains("byte [")
            && values.dataType.lastIndexOf('[') == values.dataType.indexOf('['))
            || values.dataType.startsWith("compressed")) {
          assertTrue(
              "for dataType=" + values.dataType + " expected "
                  + Arrays.toString((byte[]) values.dataValue) + " but was "
                  + Arrays.toString((byte[]) block.getDataValue()),
              Arrays.equals((byte[]) values.dataValue, (byte[]) block.getDataValue()));
        } else if (values.dataType.contains("[")) {
          // TODO: multiple dimension arrays or non-byte arrays
        } else if (values.dataValue instanceof Collection) {
          int diff = joint((Collection<?>) values.dataValue, (Collection<?>) block.getDataValue());
          assertEquals(i + ":" + values.dataType, 0, diff);
        } else if (values.dataValue instanceof IdentityHashMap) {
          // TODO
        } else if (values.dataValue instanceof Map) {
          int diff = joint((Map<?, ?>) values.dataValue, (Map<?, ?>) block.getDataValue());
          assertEquals(i + ":" + values.dataType, 0, diff);
        } else {
          assertEquals(i + ":" + values.dataType, values.dataValue, block.getDataValue());
        }
        block = block.getNextBlock();
        i++;
      }
      assertEquals("All blocks: " + inspector.getAllBlocks(), expected.size(), i);
    } finally {
      inspector.clearSnapshot();
    }

    // perform more ops

    // validate more inspection

  }
Basic integration tests for validating the off-heap implementation.
geode-core/src/integrationTest/java/org/apache/geode/internal/offheap/OffHeapValidationJUnitTest.java