protected Result getResult()

in core/org.openjdk.jmc.flightrecorder.rules.jdk/src/main/java/org/openjdk/jmc/flightrecorder/rules/jdk/memory/StringDeduplicationRule.java [115:205]


	protected Result getResult(IItemCollection items, IPreferenceValueProvider vp) {
		JavaVersion javaVersion = RulesToolkit.getJavaVersion(items);
		if (javaVersion == null) {
			return RulesToolkit.getNotApplicableResult(this,
					Messages.getString(Messages.General_TEXT_COULD_NOT_DETERMINE_JAVA_VERSION));
		}

		String stringInternalArrayType = "byte[]"; //$NON-NLS-1$
		IQuantity averageStringSize = UnitLookup.BYTE.quantity(50);

		if (!javaVersion.isGreaterOrEqualThan(JavaVersionSupport.STRING_IS_BYTE_ARRAY)) {
			stringInternalArrayType = "char[]"; //$NON-NLS-1$

			Boolean compactStrings = items.getAggregate(JdkAggregators.COMPACT_STRINGS);
			if (Boolean.FALSE.equals(compactStrings)) {
				averageStringSize = UnitLookup.BYTE.quantity(100);
			}
		}
		IItemFilter stringInternalArrayTypeFilter = ItemFilters.equals(JdkAttributes.OBJECT_CLASS_FULLNAME,
				stringInternalArrayType);

		Boolean useStringDeduplication = items.getAggregate(JdkAggregators.USE_STRING_DEDUPLICATION);
		if (Boolean.TRUE.equals(useStringDeduplication)) {
			return new Result(this, 0,
					Messages.getString(Messages.StringDeduplicationRule_RESULT_USE_STRING_DEDUPLICATION_ENABLED));
		}

		EventAvailability heapSummaryAvailable = RulesToolkit.getEventAvailability(items, JdkTypeIDs.HEAP_SUMMARY);
		if (heapSummaryAvailable != AVAILABLE) {
			return RulesToolkit.getEventAvailabilityResult(this, items, heapSummaryAvailable, JdkTypeIDs.HEAP_SUMMARY);
		}

		EventAvailability objectCountAvail = RulesToolkit.getEventAvailability(items, JdkTypeIDs.OBJECT_COUNT);
		EventAvailability objectCountAfterGcAvail = RulesToolkit.getEventAvailability(items,
				JdkTypeIDs.GC_DETAILED_OBJECT_COUNT_AFTER_GC);
		EventAvailability allocationAvail = RulesToolkit.getEventAvailability(items,
				JdkTypeIDs.ALLOC_INSIDE_TLAB /* ,ALLOC_OUTSIDE_TLAB */);
		if (objectCountAvail != AVAILABLE && objectCountAfterGcAvail != AVAILABLE && allocationAvail != AVAILABLE) {
			return RulesToolkit.getRuleRequiresAtLeastOneEventTypeResult(this, JdkTypeIDs.OBJECT_COUNT,
					JdkTypeIDs.GC_DETAILED_OBJECT_COUNT_AFTER_GC, JdkTypeIDs.ALLOC_INSIDE_TLAB,
					JdkTypeIDs.ALLOC_OUTSIDE_TLAB);
		}
		// FIXME: Add info about rule preferring object count event, and wanting heap conf or flags...

		IQuantity stringLivesetRatioAndHeapUsageLimit = vp
				.getPreferenceValue(STRING_ARRAY_LIVESET_RATIO_AND_HEAP_USAGE_LIMIT);
		IQuantity stringAllocationRatioAndHeapUsageLimit = vp
				.getPreferenceValue(STRING_ARRAY_ALLOCATION_RATIO_AND_HEAP_USAGE_LIMIT);
		String allocationFramesString = vp.getPreferenceValue(STRING_ARRAY_ALLOCATION_FRAMES);

		// Calculate heap usage
		IQuantity maxHeapSizeConf = items.getAggregate(JdkAggregators.HEAP_CONF_MAX_SIZE);
		IQuantity maxHeapSizeFlag = UnitLookup.BYTE
				.quantity(items.getAggregate(JdkAggregators.LARGEST_MAX_HEAP_SIZE_FROM_FLAG).longValue());
		IQuantity maxHeapSize = maxHeapSizeConf != null ? maxHeapSizeConf : maxHeapSizeFlag;

		String heapInfo = MessageFormat.format(
				Messages.getString(Messages.StringDeduplicationRule_RESULT_NO_MAX_HEAP_INFO), JdkTypeIDs.HEAP_CONF,
				JdkTypeIDs.ULONG_FLAG);
		double heapUsedRatio = -1;
		if (maxHeapSize != null) {
			IQuantity avgHeapUsed = items.getAggregate(JdkAggregators.AVG_HEAP_USED_AFTER_GC);
			heapUsedRatio = avgHeapUsed.ratioTo(maxHeapSize) * 100;
			heapInfo = MessageFormat.format(Messages.getString(Messages.StringDeduplicationRule_RESULT_HEAP_USAGE),
					Math.round(heapUsedRatio));
		}

		Boolean useG1GC = items.getAggregate(JdkAggregators.USE_G1_GC);
		String extraCompatInfo = ""; //$NON-NLS-1$
		if (!Boolean.TRUE.equals(useG1GC)) {
			extraCompatInfo += "<p>" + Messages.getString(Messages.StringDeduplicationRule_RESULT_NON_G1_LONG); //$NON-NLS-1$
		}
		if (!javaVersion.isGreaterOrEqualThan(JavaVersionSupport.STRING_DEDUPLICATION_SUPPORTED)) {
			extraCompatInfo += "<p>" + Messages.getString(Messages.StringDeduplicationRule_RESULT_PRE_8_20); //$NON-NLS-1$
		}

		// Calculate string internal array ratios depending on available event types
		if (objectCountAvail == AVAILABLE || objectCountAfterGcAvail == AVAILABLE) {
			String objectCountEventType = (objectCountAvail == AVAILABLE) ? JdkTypeIDs.OBJECT_COUNT
					: JdkTypeIDs.GC_DETAILED_OBJECT_COUNT_AFTER_GC;

			return getLivesetRatioResult(items, stringInternalArrayType, stringInternalArrayTypeFilter,
					averageStringSize, stringLivesetRatioAndHeapUsageLimit, objectCountEventType, heapInfo,
					heapUsedRatio, extraCompatInfo);
		} else {
			return getAllocationRatioResult(items, stringInternalArrayType, stringInternalArrayTypeFilter,
					stringAllocationRatioAndHeapUsageLimit, allocationFramesString, heapInfo, heapUsedRatio,
					extraCompatInfo);
		}
		// TODO: Check free physical memory?
	}