public void handleObjectArray()

in application/org.openjdk.jmc.joverflow/src/main/java/org/openjdk/jmc/joverflow/stats/DetailedStatsCalculator.java [378:487]


	public void handleObjectArray(JavaObjectArray objArray, JavaHeapObject[] elements) {
		if (objArray.isVisitedAsCollectionImpl()) {
			return;
		}

		numObjArrays++;
		int arraySize = objArray.getSize();
		totalObjArraysShallowSize += arraySize;
		objArray.getClazz().updateInclusiveInstanceSize(arraySize);

		boolean goodArray = true;

		if (elements.length == 0) {
//			goodArray = false;
			CollectionClassDescriptor classDesc = colDescriptors.getStandaloneArrayDescriptor(objArray);
			numLengthZeroObjArrays++;
			int ovhd = arraySize;
			lengthZeroObjArraysOvhd += ovhd;
			classDesc.addProblematicCollection(ProblemKind.LENGTH_ZERO, ovhd);
			refChain.recordCurrentRefChainForColCluster(objArray, new ArrayObjDescriptor(classDesc, 0, arraySize),
					ProblemKind.LENGTH_ZERO, ovhd);
			return;
		}

		if (elements.length == 1) {
			goodArray = false;
			CollectionClassDescriptor classDesc = colDescriptors.getStandaloneArrayDescriptor(objArray);
			numLengthOneObjArrays++;
			int ovhd = arraySize;
			lengthOneObjArraysOvhd += ovhd;
			classDesc.addProblematicCollection(ProblemKind.LENGTH_ONE, ovhd);
			refChain.recordCurrentRefChainForColCluster(objArray, new ArrayObjDescriptor(classDesc, 0, arraySize),
					ProblemKind.LENGTH_ONE, ovhd);
		}

		int nNullEntries = 0;
		boolean boxedNumsPresent = false;
		int totalBoxedNumOvhd = 0;
		for (JavaHeapObject element : elements) {
			if (element != null) {
				int primitiveNumSize = element.getClazz().getBoxedNumberSize();
				if (primitiveNumSize > 0) {
					boxedNumsPresent = true;
					// Below is how much memory we would save (or maybe lose) if we replace a
					// pointer with the primitive type array slot
					totalBoxedNumOvhd += (ptrSize - primitiveNumSize);
					JavaLazyReadObject elementObj = (JavaLazyReadObject) element;
					// If the same Number object is referenced from two places, don't count it twice
					if (!elementObj.isVisitedAsOther()) {
						elementObj.setVisitedAsOther();
						totalBoxedNumOvhd += element.getSize(); // Savings from getting rid of boxed Number
					}
				}
			} else {
				nNullEntries++;
			}
		}

		CollectionClassDescriptor classDesc = colDescriptors.getStandaloneArrayDescriptor(objArray);
		ArrayObjDescriptor arrayDesc = new ArrayObjDescriptor(classDesc, elements.length, arraySize);

		if (nNullEntries > elements.length / 2) {
			// Empty or sparse object array dangling from something other than a known collection
			goodArray = false;
			if (nNullEntries == elements.length) {
				numEmptyObjArrays++;
				int ovhd = objArray.getSize();
				emptyObjArraysOvhd += ovhd;
				classDesc.addProblematicCollection(ProblemKind.EMPTY, ovhd);
				refChain.recordCurrentRefChainForColCluster(objArray, arrayDesc, ProblemKind.EMPTY, ovhd);
			} else {
				numSparseArrays++;
				int ovhd = nNullEntries * ptrSize;
				sparseObjArraysOvhd += ovhd;
				classDesc.addProblematicCollection(ProblemKind.SPARSE_ARRAY, ovhd);
				refChain.recordCurrentRefChainForColCluster(objArray, arrayDesc, ProblemKind.SPARSE_ARRAY, ovhd);
			}
		}

		if (boxedNumsPresent) {
			numBoxedNumberArrays++;
			// In extreme cases, the overhead of boxed numbers can actually be negative. For example,
			// with 4-byte pointers, if we have 20 elements of Double[] array pointing at a single
			// Double object, we will use 4*20 + 16 = 96 bytes. However, a double[] array of the same
			// size would use 8*20 = 160 bytes. Thus we count all boxed arrays for consistency above,
			// but we add up the overhead and store the details only for those where overhead is real.
			if (totalBoxedNumOvhd > 0) {
				goodArray = false;
				boxNumObjArraysOvhd += totalBoxedNumOvhd;
				classDesc.addProblematicCollection(ProblemKind.BOXED, totalBoxedNumOvhd);
				refChain.recordCurrentRefChainForColCluster(objArray, arrayDesc, ProblemKind.BOXED, totalBoxedNumOvhd);
			}
		}

		BarArrayHandler barHandler = BarArrayHandler.createInstance(elements, colDescriptors);
		if (barHandler != null) {
			int ovhd = barHandler.calculateOverhead();
			if (ovhd > 0) {
				goodArray = false;
				numBarObjArrays++;
				barObjArraysOvhd += ovhd;
				classDesc.addProblematicCollection(ProblemKind.BAR, ovhd);
				refChain.recordCurrentRefChainForColCluster(objArray, arrayDesc, ProblemKind.BAR, ovhd);
			}
		}

		if (goodArray) { // No defects found for this array
			refChain.recordCurrentRefChainForGoodCollection(objArray, arrayDesc);
		}
	}