diff a/test/lib/jdk/test/lib/hprof/model/JavaValueArray.java b/test/lib/jdk/test/lib/hprof/model/JavaValueArray.java
--- a/test/lib/jdk/test/lib/hprof/model/JavaValueArray.java
+++ b/test/lib/jdk/test/lib/hprof/model/JavaValueArray.java
@@ -32,40 +32,18 @@
 
 import java.io.IOException;
 import java.util.Objects;
 
 /**
- * An array of values, that is, an array of ints, boolean, floats or the like.
+ * An array of values, that is, an array of ints, boolean, floats, etc.
+ * or flat array of primitive objects.
  *
  * @author      Bill Foote
  */
 public class JavaValueArray extends JavaLazyReadObject
                 /*imports*/ implements ArrayTypeCodes {
 
-    private static String arrayTypeName(byte sig) {
-        switch (sig) {
-            case 'B':
-                return "byte[]";
-            case 'Z':
-                return "boolean[]";
-            case 'C':
-                return "char[]";
-            case 'S':
-                return "short[]";
-            case 'I':
-                return "int[]";
-            case 'F':
-                return "float[]";
-            case 'J':
-                return "long[]";
-            case 'D':
-                return "double[]";
-            default:
-                throw new RuntimeException("invalid array element sig: " + sig);
-        }
-    }
-
     private static int elementSize(byte type) {
         switch (type) {
             case 'B':
             case 'Z':
                 return 1;
@@ -97,11 +75,11 @@
     protected final long readValueLength() throws IOException {
         long offset = getOffset() + idSize() + 4;
         // length of the array in elements
         long len = buf().getInt(offset);
         // byte length of array
-        return len * elementSize(getElementType());
+        return len * elementSize(getRealElementType());
     }
 
     private long dataStartOffset() {
         return getOffset() + idSize() + 4 + 4 + 1;
     }
@@ -169,20 +147,29 @@
                                   res[i] = new JavaDouble(doubleAt(offset));
                                   offset += 8;
                               }
                               return res;
                 }
+                case 'Q': {
+                    for (int i = 0; i < len; i++) {
+                        res[i] = new InlinedJavaObject(flatArrayElementClass, offset);
+                        offset += flatArrayElementClass.getInlinedInstanceSize();
+                    }
+                    return res;
+                }
                 default: {
                              throw new RuntimeException("unknown primitive type?");
                 }
             }
         }
     }
 
     // JavaClass set only after resolve.
     private JavaClass clazz;
 
+    private long objID;
+
     // This field contains elementSignature byte and
     // divider to be used to calculate length. Note that
     // length of content byte[] is not same as array length.
     // Actual array length is (byte[].length / divider)
     private int data;
@@ -194,32 +181,58 @@
     private static final int LENGTH_DIVIDER_MASK = 0x0FF00;
 
     // Number of bits to shift to get length divider
     private static final int LENGTH_DIVIDER_SHIFT = 8;
 
-    public JavaValueArray(byte elementSignature, long offset) {
+    // Flat array support.
+    private JavaClass flatArrayElementClass;
+
+    public JavaValueArray(long id, byte elementSignature, long offset) {
         super(offset);
+        this.objID = id;
         this.data = (elementSignature & SIGNATURE_MASK);
     }
 
     public JavaClass getClazz() {
         return clazz;
     }
 
+    public boolean isFlatArray() {
+        return flatArrayElementClass != null;
+    }
+
+    public JavaClass getFlatElementClazz() {
+        return flatArrayElementClass;
+    }
+
     public void visitReferencedObjects(JavaHeapObjectVisitor v) {
         super.visitReferencedObjects(v);
     }
 
     public void resolve(Snapshot snapshot) {
         if (clazz instanceof JavaClass) {
             return;
         }
-        byte elementSig = getElementType();
-        clazz = snapshot.findClass(arrayTypeName(elementSig));
-        if (clazz == null) {
-            clazz = snapshot.getArrayClass("" + ((char) elementSig));
+
+        byte elementType = getElementType();
+        String elementSig = "" + (char)elementType;
+        // Check if this is a flat array of primitive objects.
+        Number elementClassID = snapshot.findFlatArrayElementType(objID);
+        if (elementClassID != null) {
+            // This is flat array.
+            JavaHeapObject elementClazz = snapshot.findThing(getIdValue(elementClassID));
+            if (elementClazz instanceof JavaClass elementJavaClazz) {
+                flatArrayElementClass = elementJavaClazz;
+                // need to resolve the element class
+                flatArrayElementClass.resolve(snapshot);
+                elementSig = "Q" + flatArrayElementClass.getName() + ";";
+            } else {
+                // The class not found.
+                System.out.println("WARNING: flat array element class not found");
+            }
         }
+        clazz = snapshot.getArrayClass(elementSig);
         getClazz().addInstance(this);
         super.resolve(snapshot);
     }
 
     public int getLength() {
@@ -241,10 +254,13 @@
                 break;
             case 'J':
             case 'D':
                 divider = 8;
                 break;
+            case 'Q':
+                divider = flatArrayElementClass.getInlinedInstanceSize();
+                break;
             default:
                 throw new RuntimeException("unknown primitive type: " +
                                 elementSignature);
             }
             data |= (divider << LENGTH_DIVIDER_SHIFT);
@@ -255,10 +271,14 @@
     public JavaThing[] getElements() {
         return getValue();
     }
 
     public byte getElementType() {
+        return isFlatArray() ? (byte)'Q' : getRealElementType();
+    }
+
+    private byte getRealElementType() {
         return (byte) (data & SIGNATURE_MASK);
     }
 
     private void checkIndex(int index) {
         Objects.checkIndex(index, getLength());
@@ -277,11 +297,11 @@
     public String valueString(boolean bigLimit) {
         // Char arrays deserve special treatment
         StringBuilder result;
         JavaThing[] things = getValue();
         byte elementSignature = getElementType();
-        if (elementSignature == 'C')  {
+        if (elementSignature == 'C' && !isFlatArray())  {
             result = new StringBuilder();
             for (int i = 0; i < things.length; i++) {
                 result.append(things[i]);
             }
         } else {
@@ -336,10 +356,14 @@
                     case 'D': {         // double
                         double val = ((JavaDouble)things[i]).value;
                         result.append(val);
                         break;
                     }
+                    case 'Q': {
+                        InlinedJavaObject obj = (InlinedJavaObject)things[i];
+                        result.append(obj);
+                    }
                     default: {
                         throw new RuntimeException("unknown primitive type?");
                     }
                 }
             }
