void (@NotNull Deque<? super BackLink<?>> queue, @NotNull Object root, @NotNull BackLink<?> backLink, @NotNull Predicate<Object> shouldExamineValue) { Class<?> rootClass = root.getClass(); for (Field field : getAllFields(rootClass)) { String fieldName = field.getName(); // do not follow weak/soft refs if (root instanceof Reference && ("referent".equals(fieldName) || "discovered".equals(fieldName))) { continue; } Object value; try { value = field.get(root); } catch (IllegalArgumentException | IllegalAccessException e) { throw new RuntimeException(e); } queue(value, field, null, backLink, queue, shouldExamineValue); } if (rootClass.isArray()) { try { Object[] objects = (Object[])root; for (int i = 0; i < objects.length; i++) { Object value = objects[i]; queue(value, null, "["+i+"]", backLink, queue, shouldExamineValue); } } catch (ClassCastException ignored) { } } // check for objects leaking via static fields. process initialized classes only if (root instanceof Class && isInitialized((Class<?>)root)) { for (Field field : getAllFields((Class<?>)root)) { if ((field.getModifiers() & Modifier.STATIC) == 0) continue; try { Object value = field.get(null); queue(value, field, null, backLink, queue, shouldExamineValue); } catch (IllegalAccessException ignored) { } } } }