@Override
  public Object getDeserializedValue(Region r, RegionEntry re) {
    Object v = value;
    if (v instanceof byte[]) {
      // org.apache.geode.internal.cache.GemFireCache.getInstance().getLogger().info("DEBUG
      // getDeserializedValue r=" + r + " re=" + re, new RuntimeException("STACK"));
      EvictableEntry le = null;
      if (re != null) {
        assert r != null;
        if (re instanceof EvictableEntry) {
          le = (EvictableEntry) re;
        }
      }
      if (le != null) {
        if (r instanceof PartitionedRegion) {
          r = ((PartitionedRegion) r).getBucketRegion(re.getKey());
        }
        boolean callFinish = false;
        RegionMap regionMap = null;
        if (r != null) { // fix for bug 44795
          regionMap = ((InternalRegion) r).getRegionMap();
        }
        boolean threadAlreadySynced = Thread.holdsLock(le);
        boolean isCacheListenerInvoked = re.isCacheListenerInvocationInProgress();
        synchronized (le) {
          v = value;
          if (!(v instanceof byte[])) {
            return v;
          }
          v = EntryEventImpl.deserialize((byte[]) v);
          if (threadAlreadySynced && !isCacheListenerInvoked) {
            // to fix bug 43355 and 43409 don't change the value form
            // if the thread that called us was already synced.
            return v;
          }
          if (!(v instanceof PdxInstance)) {
            value = v;
            if (regionMap != null) {
              callFinish = regionMap.beginChangeValueForm(le, this, v);
            }
          }
        }
        if (callFinish && !isCacheListenerInvoked) {
          regionMap.finishChangeValueForm();
        }
      } else {
        // we sync on this so we will only do one deserialize
        synchronized (this) {
          v = value;
          if (!(v instanceof byte[])) {
            return v;
          }
          v = EntryEventImpl.deserialize((byte[]) v);
          if (!(v instanceof PdxInstance)) {
            value = v;
          }
          // ObjectSizer os = null;
          // if (r != null) {
          // EvictionAttributes ea = r.getAttributes().getEvictionAttributes();
          // if (ea != null) {
          // os = ea.getObjectSizer();
          // }
          // int vSize = CachedDeserializableFactory.calcMemSize(v, os, false, false);
          // if (vSize != -1) {
          // int oldSize = this.valueSize;
          // this.valueSize = vSize;
          // if (r instanceof BucketRegion) {
          // BucketRegion br = (BucketRegion)r;
          // br.updateBucketMemoryStats(vSize - oldSize);
          // }
          // // @todo do we need to update some lru stats since the size changed?
          // }
          // // If vSize == -1 then leave valueSize as is which is the serialized size.
        }
      }
    }
    return v;
  }
Create a new instance with an object and it's size. Note the caller decides if objectSize is
the memory size or the serialized size.
geode-core/src/main/java/org/apache/geode/internal/cache/VMCachedDeserializable.java