Result calculateOverhead()

in application/org.openjdk.jmc.joverflow/src/main/java/org/openjdk/jmc/joverflow/stats/WeakMapHandler.java [78:148]


	Result calculateOverhead() {
		JavaHeapObject keysAndValues[][] = colDesc.getKeysAndValues();
		if (keysAndValues[0].length == 0) {
			return null;
		}

		JavaHeapObject[] keys = keysAndValues[0];
		SimpleIdentitySet<JavaHeapObject> keySet = new SimpleIdentitySet<>(keys.length);
		for (JavaHeapObject key : keys) {
			if (key != null) {
				keySet.add(key);
			}
		}
		// Important: this operation can only be performed if the empty check above is done!
		// Let's comment it out. Safety is more important than a little saved memory
		// keysAndValues[0] = null;   // Help the GC
		JavaHeapObject[] values = keysAndValues[1];

		int ovhd = 0;
		String valueTypeAndFieldSample = null;
		for (JavaHeapObject value : values) {
			if (value instanceof JavaObject) {
				JavaObject valueObj = (JavaObject) value;
				// A weak reference back to key is ok
				if (valueObj.getClazz().isOrSubclassOf(Constants.WEAK_REFERENCE)) {
					break;
				}

				JavaThing[] fields = valueObj.getFields(false);
				for (int i = 0; i < fields.length; i++) {
					JavaThing fieldThing = fields[i];
					if (fieldThing == null || !(fieldThing instanceof JavaHeapObject)) {
						continue;
					}
					JavaHeapObject field = (JavaHeapObject) fieldThing;
					if (keySet.contains(field)) {
						ovhd += field.getSize() + valueObj.getSize();
						if (valueTypeAndFieldSample == null) {
							valueTypeAndFieldSample = getStringForValueAndField(valueObj, i);
						}
						break;
					}
				}
			} else if (value instanceof JavaObjectArray) {
				JavaHeapObject[] elements = ((JavaObjectArray) value).getElements();
				for (JavaHeapObject element : elements) {
					if (element == null) {
						continue;
					}
					// A weak reference back to key is ok
					if (element.getClazz().isOrSubclassOf(Constants.WEAK_REFERENCE)) {
						continue;
					}

					if (keySet.contains(element)) {
						ovhd += element.getSize() + value.getSize();
						if (valueTypeAndFieldSample == null) {
							valueTypeAndFieldSample = value.getClazz().getName();
						}
						break;
					}
				}
			}
		}

		if (ovhd > 0) {
			return new Result(ovhd, valueTypeAndFieldSample);
		} else {
			return null;
		}
	}