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?
}