private void doSearch(Object root, VisitStack stack)
      throws IllegalArgumentException, IllegalAccessException {
    Class<?> clazz = root.getClass();
    boolean includeStatics = stack.shouldIncludeStatics(clazz);
    Field[] nonPrimitiveFields = getNonPrimitiveFields(clazz, includeStatics);

    if (nonPrimitiveFields == NON_PRIMITIVE_ARRAY) {
      int length = Array.getLength(root);
      for (int i = 0; i < length; i++) {
        Object value = Array.get(root, i);
        stack.add(root, value);
      }
      return;
    }

    if (includeStatics) {
      for (Field field : getStaticFields(clazz)) {
        Object value = field.get(root);
        stack.add(root, value);
      }
    }

    for (Field field : nonPrimitiveFields) {
      Object value = field.get(root);
      stack.add(root, value);
    }
  }
Visit all objects reachable from a given root object, using a breadth first search. Using this
method requires some heap space - probably between 8 - 30 bytes per reachable object.

@param root object to traverse from
@param visitor a visitor to visit each node
@param includeStatics if true, then first time we see a new object type, all of its static
       fields will be visited.
geode-core/src/main/java/org/apache/geode/internal/size/ObjectTraverser.java