/**
* ICE Futures, US
*/
package test.org.helios.apmrouter.performance;
import org.helios.apmrouter.util.ResourceHelper.NamedMemoryUsage;
import java.lang.management.GarbageCollectorMXBean;
import java.lang.management.ManagementFactory;
import java.lang.management.MemoryUsage;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
/**
* <p>Title: BenchmarkResult</p>
* <p>Description: Container class and tabulator for a benchmark test</p>
* <p>Company: ICE Futures US</p>
* @author Whitehead (nicholas.whitehead@theice.com)
* @version $LastChangedRevision$
* <p><code>test.org.helios.apmrouter.performance.BenchmarkResult</code></p>
*/
public class BenchmarkResult {
/** Heap and non-Heap memory usage when the test starts */
private final MemoryUsage[] startingUsage;
/** GC collections and times at start */
private final Map<String, long[]> startingGc;
/** The heap delta memory usage */
private NamedMemoryUsage heapMemoryDelta = null;
/** The non-heap delta memory usage */
private NamedMemoryUsage nonHeapMemoryDelta = null;
/** GC collection and time deltas at end */
private final Map<String, long[]> deltaGc;
/** The aggregated per thread metrics */
private AggregatedThreadBenchmarkResult threadBenchmark = null;
/**
* Creates a new BenchmarkResult
* @param startingUsage Heap and non-Heap memory usage when the test starts
*/
public BenchmarkResult(MemoryUsage[] startingUsage) {
this.startingUsage = startingUsage;
List<GarbageCollectorMXBean> collectors = ManagementFactory.getGarbageCollectorMXBeans();
startingGc = new HashMap<String, long[]>(collectors.size());
deltaGc = new HashMap<String, long[]>(collectors.size());
for(GarbageCollectorMXBean gc: collectors) {
startingGc.put(gc.getName(), new long[]{gc.getCollectionCount(), gc.getCollectionTime()});
}
}
/**
* Closes the benchmark result and tabulates the results
* @param endingUsage The ending memory usage (heap and non-heap)
*/
public void end(MemoryUsage[] endingUsage, List<Future<ThreadBenchmarkResult>> threadTasks) {
heapMemoryDelta = new NamedMemoryUsage(endingUsage[0], "Heap State");
nonHeapMemoryDelta = new NamedMemoryUsage(endingUsage[1], "NonHeap State");
for(GarbageCollectorMXBean gc: ManagementFactory.getGarbageCollectorMXBeans()) {
long[] starting = startingGc.get(gc.getName());
deltaGc.put(gc.getName(), new long[]{gc.getCollectionCount()-starting[0], gc.getCollectionTime()-starting[1]});
}
ThreadBenchmarkResult[] threadResults = new ThreadBenchmarkResult[threadTasks.size()];
for(int i = 0; i < threadTasks.size(); i++) {
try {
threadResults[i] = threadTasks.get(i).get();
} catch (InterruptedException e) {
throw new RuntimeException("Interrupted Exception waiting for thread result, which should not happen...", e);
} catch (ExecutionException e) {
throw new RuntimeException("Execution Exception waiting for thread result, which should not happen...", e);
}
}
threadBenchmark = AggregatedThreadBenchmarkResult.aggregate(threadResults);
}
/**
* Returns the heap memory delta
* @return the heapMemoryDelta
*/
public NamedMemoryUsage getHeapMemoryDelta() {
return heapMemoryDelta;
}
/**
* Returns the non-heap memory delta
* @return the nonHeapMemoryDelta
*/
public NamedMemoryUsage getNonHeapMemoryDelta() {
return nonHeapMemoryDelta;
}
/**
* Returns the GC activity delta
* @return the deltaGc
*/
public Map<String, long[]> getDeltaGc() {
return deltaGc;
}
/**
* {@inheritDoc}
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
StringBuilder b = new StringBuilder("BenchmarkResult [");
b.append("\n\t").append("Heap Memory State:");
for(Map.Entry<String, Long> memEntry: heapMemoryDelta.getUsageMap().entrySet()) {
b.append("\n\t\t").append(memEntry.getKey()).append(":").append(memEntry.getValue());
}
b.append("\n\t").append("NonHeap Memory State:");
for(Map.Entry<String, Long> memEntry: nonHeapMemoryDelta.getUsageMap().entrySet()) {
b.append("\n\t\t").append(memEntry.getKey()).append(":").append(memEntry.getValue());
}
b.append("\n\t").append("GC Activity:");
for(Map.Entry<String, long[]> gcEntry: deltaGc.entrySet()) {
b.append("\n\t\t").append(gcEntry.getKey()).append(":")
.append("\n\t\t\tCollections:").append(gcEntry.getValue()[0])
.append("\n\t\t\tCollection Times:").append(gcEntry.getValue()[1]);
}
b.append("\n\t").append("Workload Summary:\n").append(threadBenchmark);
b.append("\n]");
return b.toString();
}
}