Skip to content

Commit

Permalink
Improvements (#1)
Browse files Browse the repository at this point in the history
* Initial Commit. Reformat, Rearrange, CheckStyle and Tests required.

* Added AllocationRate test classes

* Pretty formatting of Jvm Profiling output.

* Fix failing tests

* Minor test improvements

* Add licence headers

* Minor improvements

* Fix build issue and simplify exception management

* Simplify exception management

* Time stamp should have no reason to be negative

* Fix typo

* Fix compilation warning

* Separation of concerns and code simplification

* Extract methods

* Allocation duration has no reason to be negative

* Remove local variable

* Should return an empty string if allocation duration is zero

* Simplify code by removing not possible test cases

* Remove compilation warning

* Item collection has no reason to be null

* Thre is no reason to don't have JFR events

* With this removal, a blank string is always return when no allocation events

* Invert code lines

* Remove local variables

* Improve separation of concerns

Co-authored-by: Edward Rose <exr194@cs.bham.ac.uk>
  • Loading branch information
jeanbisutti and Edward Rose committed May 29, 2020
1 parent 3225e8f commit 285a32f
Show file tree
Hide file tree
Showing 14 changed files with 529 additions and 63 deletions.
Expand Up @@ -14,24 +14,40 @@
public enum AllocationUnit {

BYTE(1) {
@Override
public String shortFormat() {
return "bytes";
}
@Override
public String toString() {
return "bytes";
}
}
, KILO_BYTE(1024) {
@Override
public String shortFormat() {
return "KiB";
}
@Override
public String toString() {
return "Kilo bytes";
}
}
, MEGA_BYTE(1024 * 1024) {
@Override
public String shortFormat() {
return "MiB";
}
@Override
public String toString() {
return "Mega bytes";
}
}
, GIGA_BYTE(1024 * 1024 * 1024) {
@Override
public String shortFormat() {
return "GiB";
}
@Override
public String toString() {
return "Giga bytes";
Expand All @@ -50,4 +66,6 @@ public int getValueInBytes() {
return valueInBytes;
}

public abstract String shortFormat();

}
Expand Up @@ -21,20 +21,44 @@ public class ByteAllocationMeasureFormatter {

private ByteAllocationMeasureFormatter() {}

public String format(Allocation allocation) {
public String formatWithAllocationInBytes(Allocation allocation) {

if(isByteOrderOfMagnitude(allocation)) {
return formatAllocationInBytes(allocation);
} else if(isKiloByteOrderOfMagnitude(allocation)) {
String formattedAllocation = formatAllocationInKiloBytes(allocation);
return formatByteSuffixAllocationValue(formattedAllocation, allocation);
} else if(isMegaByteOrderOfMagnitude(allocation)) {
String formattedAllocation = formatAllocationInMegaBytes(allocation);
return formatByteSuffixAllocationValue(formattedAllocation, allocation);
}
if(isKiloByteOrderOfMagnitude(allocation)) {
return formatAllocationInKiloBytes(allocation)
+ formatInByteAllocationBetweenParentheses(allocation);
}
if(isMegaByteOrderOfMagnitude(allocation)) {
return formatAllocationInMegaBytes(allocation)
+ formatInByteAllocationBetweenParentheses(allocation);
}

String formattedAllocation = formatAllocationInGigaBytes(allocation);
return formatByteSuffixAllocationValue(formattedAllocation, allocation);
return formatAllocationInGigaBytes(allocation)
+ formatInByteAllocationBetweenParentheses(allocation);

}

public String shortFormat(double allocationInBytes) {

if(allocationInBytes < 1024) {
return "" + allocationInBytes + " " + AllocationUnit.BYTE.shortFormat();
}
if(allocationInBytes < 1024 * 1024) {
double kiloByteValue = allocationInBytes / 1024;
String formattedAllocationValue = formatAllocationValue(kiloByteValue);
return formattedAllocationValue + " " + AllocationUnit.KILO_BYTE.shortFormat();
}
if(allocationInBytes < Math.pow(1024, 3)) {
double megaByteValue = allocationInBytes / Math.pow(1024, 2);
String formattedAllocationValue = formatAllocationValue(megaByteValue);
return formattedAllocationValue + " " + AllocationUnit.MEGA_BYTE.shortFormat();
}

double gigaByteValue = allocationInBytes / Math.pow(1024, 3);
String formattedAllocationValue = formatAllocationValue(gigaByteValue);
return formattedAllocationValue + " " + AllocationUnit.GIGA_BYTE.shortFormat();

}

Expand Down Expand Up @@ -100,11 +124,6 @@ private String formatAllocationValue(double allocationValue) {

}

private String formatByteSuffixAllocationValue(String prefix, Allocation allocationValue)
{
return prefix + formatInByteAllocationBetweenParentheses(allocationValue);
}

private String formatInByteAllocationBetweenParentheses(Allocation allocationValue) {
DecimalFormat decimalFormat = buildBytePrefixFormatter();
return " (" + decimalFormat.format(allocationValue.getValue()) + " bytes)";
Expand Down
Expand Up @@ -32,8 +32,8 @@ public PerfIssue verifyPerfIssue(ExpectMaxHeapAllocation annotation, Allocation

String assertionMessage =
"Expected allocation (test method thread) to be less than "
+ byteAllocationMeasureFormatter.format(maxExpectedAllocation)
+ " but is " + byteAllocationMeasureFormatter.format(measuredAllocation) + ".";
+ byteAllocationMeasureFormatter.formatWithAllocationInBytes(maxExpectedAllocation)
+ " but is " + byteAllocationMeasureFormatter.formatWithAllocationInBytes(measuredAllocation) + ".";
String description = assertionMessage + System.lineSeparator() + measuredAllocation.getComment();

return new PerfIssue(description);
Expand Down
Expand Up @@ -27,7 +27,7 @@ private MeasureHeapAllocationPerfVerifier() { }

@Override
public PerfIssue verifyPerfIssue(MeasureHeapAllocation annotation, Allocation measuredAllocation) {
String allocationAsString = byteAllocationMeasureFormatter.format(measuredAllocation);
String allocationAsString = byteAllocationMeasureFormatter.formatWithAllocationInBytes(measuredAllocation);
PrintWriter pw = new PrintWriter(System.out);
pw.printf(annotation.format(), allocationAsString);
// do not call close on pw since it will call close on System.out
Expand Down
Expand Up @@ -25,18 +25,18 @@ private NoHeapAllocationPerfVerifier() {}

private final ByteAllocationMeasureFormatter byteAllocationMeasureFormatter = ByteAllocationMeasureFormatter.INSTANCE;


@Override
public PerfIssue verifyPerfIssue(ExpectNoHeapAllocation annotation, Allocation measuredAllocation) {

if(!ZERO_ALLOCATION.isEqualTo(measuredAllocation)) {
String assertionMessage =
"Expected allocation (test method thread) to be 0 but is " + byteAllocationMeasureFormatter.format(measuredAllocation) + ".";
"Expected allocation (test method thread) to be 0 but is " + byteAllocationMeasureFormatter.formatWithAllocationInBytes(measuredAllocation) + ".";
String description = assertionMessage + System.lineSeparator() + measuredAllocation.getComment();
return new PerfIssue(description);
}

return PerfIssue.NONE;

}

}
Expand Up @@ -18,16 +18,18 @@

import static org.quickperf.jvm.jmc.value.ProfilingInfo.*;

public class DisplayJvmProfilingValueVerifier implements VerifiablePerformanceIssue<ProfileJvm, JfrEventsMeasure> {
public class DisplayJvmProfilingValueVerifier implements
VerifiablePerformanceIssue<ProfileJvm, JfrEventsMeasure> {

public static DisplayJvmProfilingValueVerifier INSTANCE = new DisplayJvmProfilingValueVerifier();

private static final String LINE_SEPARATOR = System.lineSeparator();

private static final String LINE = "-----------------------------------------------------------------------------" + LINE_SEPARATOR;
private static final String LINE = "------------------------------------------------------------------------------" + LINE_SEPARATOR;


private DisplayJvmProfilingValueVerifier() { }
private DisplayJvmProfilingValueVerifier() {
}

@Override
public PerfIssue verifyPerfIssue(ProfileJvm annotation, JfrEventsMeasure jfrEventsMeasure) {
Expand All @@ -39,6 +41,7 @@ public PerfIssue verifyPerfIssue(ProfileJvm annotation, JfrEventsMeasure jfrEven
String allocationTotal = ALLOCATION_TOTAL.formatAsString(jfrEvents);
String insideTlabSum = ALLOC_INSIDE_TLAB_SUM.formatAsString(jfrEvents);
String outsideTlabSum = ALLOC_OUTSIDE_TLAB_SUM.formatAsString(jfrEvents);
String allocationRate = ALLOCATION_RATE.formatAsString(jfrEvents);

String totalGcPause = TOTAL_GC_PAUSE.formatAsString(jfrEvents);
String gcPause = LONGEST_GC_PAUSE.formatAsString(jfrEvents);
Expand All @@ -64,38 +67,41 @@ public PerfIssue verifyPerfIssue(ProfileJvm annotation, JfrEventsMeasure jfrEven

String osVersion = OS_VERSION.formatAsString(jfrEvents);

StringWidthAdapter thirteen = new StringWidthAdapter(13);
StringWidthAdapter twelveLength = new StringWidthAdapter(12);

StringWidthAdapter fifteenLength = new StringWidthAdapter(15);

StringWidthAdapter twentyNineLength = new StringWidthAdapter(29);

StringWidthAdapter twentyEightLength = new StringWidthAdapter(28);
StringWidthAdapter thirtyLength = new StringWidthAdapter(30);

String text =
LINE
+ " ALLOCATION (estimations)" + " | " + "GARBAGE COLLECTION " + "| THROWABLE" + LINE_SEPARATOR
+ " Total : " + thirteen.adapt(allocationTotal) + "| " + twentyNineLength.adapt("Total pause: " + totalGcPause ) + "| Exception: " + exceptionsCount +LINE_SEPARATOR
+ " Inside TLAB : " + thirteen.adapt(insideTlabSum) + "| " + twentyNineLength.adapt("Longest GC pause: " + gcPause) + "| Error: " + errorCount + LINE_SEPARATOR
+ " Outside TLAB: " + thirteen.adapt(outsideTlabSum) + "| " + twentyNineLength.adapt("") + "| Throwable: " +throwablesCount + LINE_SEPARATOR
+ LINE
+ twentyEightLength.adapt(" COMPILATION") + "| " + "CODE CACHE" + LINE_SEPARATOR
+ twentyEightLength.adapt(" Number: " + compilationsCount) + "| " + codeCacheFullCount + LINE_SEPARATOR
+ twentyEightLength.adapt(" Longest: " + longestCompilation) + "| " + LINE_SEPARATOR
+ LINE
+ " " + "JVM" + LINE_SEPARATOR
+ " Name: " + jvmName + LINE_SEPARATOR
+ " Version: " + jvmVersion + LINE_SEPARATOR
+ " Arguments: " + jvmArguments + LINE_SEPARATOR
+ LINE
+ " " + "HARDWARE" + LINE_SEPARATOR
+ " Hardware threads: " + minHwThreads + LINE_SEPARATOR
+ " Cores: " + minNumberOfCores + LINE_SEPARATOR
+ " Sockets: " + minNumberOfSockets + LINE_SEPARATOR
+ " CPU: " + LINE_SEPARATOR
+ cpuDescription + LINE_SEPARATOR
+ LINE
+ " OS:" + LINE_SEPARATOR
+ osVersion + LINE_SEPARATOR
+ LINE;
LINE
+ " ALLOCATION (estimations)" + " | " + "GARBAGE COLLECTION " + "| THROWABLE" + LINE_SEPARATOR
+ " Total : " + fifteenLength.adapt(allocationTotal) + "| " + twentyNineLength.adapt("Total pause: " + totalGcPause) + "| Exception: " + exceptionsCount + LINE_SEPARATOR
+ " Inside TLAB : " + fifteenLength.adapt(insideTlabSum) + "| " + twentyNineLength.adapt("Longest GC pause: " + gcPause) + "| Error: " + errorCount + LINE_SEPARATOR
+ " Outside TLAB: " + fifteenLength.adapt(outsideTlabSum) + "| " + twentyNineLength.adapt("") + "| Throwable: " + throwablesCount + LINE_SEPARATOR
+ " Allocation rate: " + twelveLength.adapt(allocationRate) + "| " + twentyNineLength.adapt("") + "|" + LINE_SEPARATOR
+ LINE
+ thirtyLength.adapt(" COMPILATION") + "| " + "CODE CACHE" + LINE_SEPARATOR
+ thirtyLength.adapt(" Number: " + compilationsCount) + "| " + codeCacheFullCount + LINE_SEPARATOR
+ thirtyLength.adapt(" Longest: " + longestCompilation) + "| " + LINE_SEPARATOR
+ LINE
+ " " + "JVM" + LINE_SEPARATOR
+ " Name: " + jvmName + LINE_SEPARATOR
+ " Version: " + jvmVersion + LINE_SEPARATOR
+ " Arguments: " + jvmArguments + LINE_SEPARATOR
+ LINE
+ " " + "HARDWARE" + LINE_SEPARATOR
+ " Hardware threads: " + minHwThreads + LINE_SEPARATOR
+ " Cores: " + minNumberOfCores + LINE_SEPARATOR
+ " Sockets: " + minNumberOfSockets + LINE_SEPARATOR
+ " CPU: " + LINE_SEPARATOR
+ cpuDescription + LINE_SEPARATOR
+ LINE
+ " OS:" + LINE_SEPARATOR
+ osVersion + LINE_SEPARATOR
+ LINE;

System.out.println(text);

Expand Down
Expand Up @@ -16,6 +16,9 @@
import org.openjdk.jmc.common.item.IItemCollection;
import org.openjdk.jmc.common.unit.IQuantity;
import org.openjdk.jmc.flightrecorder.jdk.JdkAggregators;
import org.quickperf.jvm.jmc.value.allocationrate.AllocationRate;
import org.quickperf.jvm.jmc.value.allocationrate.AllocationRateFormatter;
import org.quickperf.jvm.jmc.value.allocationrate.AllocationRateRetriever;

public enum ProfilingInfo {

Expand Down Expand Up @@ -271,7 +274,6 @@ public String getLabel() {
}
,
OS_VERSION {

@Override
public String formatAsString(IItemCollection jfrEvents) {
return formatAsString(jfrEvents, JdkAggregators.OS_VERSION, String.class);
Expand All @@ -282,8 +284,24 @@ public String getLabel() {
return getLabel(JdkAggregators.OS_VERSION, String.class);
}

}
;
},
ALLOCATION_RATE {
@Override
public String formatAsString(IItemCollection jfrEvents) {


AllocationRate allocationRate = AllocationRateRetriever.INSTANCE
.retrieveAllocationRateFrom(jfrEvents);

return AllocationRateFormatter.INSTANCE.format(allocationRate);

}

@Override
public String getLabel() {
return "Allocation Rate";
}
};

public abstract String formatAsString(IItemCollection jfrEvents);

Expand All @@ -292,7 +310,7 @@ public String getLabel() {
@SuppressWarnings("unchecked")
String getLabel(IAggregator aggregator, Class<?> type) {

if(type.isAssignableFrom(IQuantity.class)) {
if (type.isAssignableFrom(IQuantity.class)) {
return getLabelFrom(aggregator);
}

Expand Down
@@ -0,0 +1,37 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
*
* Copyright 2019-2020 the original author or authors.
*/

package org.quickperf.jvm.jmc.value.allocationrate;

public class AllocationRate {

public static final AllocationRate NONE = new AllocationRate();

private AllocationRate() { }

private long totalAllocationInBytes;

private double allocationDurationInMs;

public AllocationRate(long totalAllocationInBytes, double allocationDurationInMs) {
this.totalAllocationInBytes = totalAllocationInBytes;
this.allocationDurationInMs = allocationDurationInMs;
}

public double getValueInBytesBySecond() {
return (totalAllocationInBytes / allocationDurationInMs) * 1000;
}

public boolean isNone() {
return this == NONE;
}

}
@@ -0,0 +1,38 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
*
* Copyright 2019-2020 the original author or authors.
*/

package org.quickperf.jvm.jmc.value.allocationrate;

import org.quickperf.jvm.allocation.ByteAllocationMeasureFormatter;

public class AllocationRateFormatter {

public static final AllocationRateFormatter INSTANCE = new AllocationRateFormatter();

private final ByteAllocationMeasureFormatter byteAllocationMeasureFormatter = ByteAllocationMeasureFormatter.INSTANCE;

private AllocationRateFormatter() { }

public String format(AllocationRate allocationRate) {

if (allocationRate.isNone()) {
return " ";
}

double allocationRateInBytesPerSecond = allocationRate.getValueInBytesBySecond();

return byteAllocationMeasureFormatter.shortFormat(allocationRateInBytesPerSecond) + "/s";

}



}

0 comments on commit 285a32f

Please sign in to comment.