提交 cfbdf443 authored 作者: andrei's avatar andrei

GC overhead calculation and reporting on performance/scalability tests

上级 d8eaa1f6
...@@ -22,7 +22,7 @@ import org.h2.util.New; ...@@ -22,7 +22,7 @@ import org.h2.util.New;
/** /**
* Utility methods * Utility methods
*/ */
public class DataUtils { public final class DataUtils {
/** /**
* An error occurred while reading from the file. * An error occurred while reading from the file.
...@@ -758,8 +758,8 @@ public class DataUtils { ...@@ -758,8 +758,8 @@ public class DataUtils {
int size = arguments.length; int size = arguments.length;
if (size > 0) { if (size > 0) {
Object o = arguments[size - 1]; Object o = arguments[size - 1];
if (o instanceof Exception) { if (o instanceof Throwable) {
e.initCause((Exception) o); e.initCause((Throwable) o);
} }
} }
return e; return e;
...@@ -776,6 +776,7 @@ public class DataUtils { ...@@ -776,6 +776,7 @@ public class DataUtils {
public static String formatMessage(int errorCode, String message, public static String formatMessage(int errorCode, String message,
Object... arguments) { Object... arguments) {
// convert arguments to strings, to avoid locale specific formatting // convert arguments to strings, to avoid locale specific formatting
arguments = arguments.clone();
for (int i = 0; i < arguments.length; i++) { for (int i = 0; i < arguments.length; i++) {
Object a = arguments[i]; Object a = arguments[i];
if (!(a instanceof Exception)) { if (!(a instanceof Exception)) {
...@@ -936,10 +937,10 @@ public class DataUtils { ...@@ -936,10 +937,10 @@ public class DataUtils {
* @param <K> the key type * @param <K> the key type
* @param <V> the value type * @param <V> the value type
*/ */
public static class MapEntry<K, V> implements Map.Entry<K, V> { public static final class MapEntry<K, V> implements Map.Entry<K, V> {
private final K key; private final K key;
private V value; private final V value;
public MapEntry(K key, V value) { public MapEntry(K key, V value) {
this.key = key; this.key = key;
......
...@@ -8,6 +8,7 @@ package org.h2.util; ...@@ -8,6 +8,7 @@ package org.h2.util;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.lang.management.GarbageCollectorMXBean;
import java.lang.management.ManagementFactory; import java.lang.management.ManagementFactory;
import java.lang.management.OperatingSystemMXBean; import java.lang.management.OperatingSystemMXBean;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
...@@ -314,6 +315,17 @@ public class Utils { ...@@ -314,6 +315,17 @@ public class Utils {
return max / 1024; return max / 1024;
} }
public static long getGarbageCollectionTime() {
long totalGCTime = 0;
for (GarbageCollectorMXBean gcMXBean : ManagementFactory.getGarbageCollectorMXBeans()) {
long collectionTime = gcMXBean.getCollectionTime();
if(collectionTime > 0) {
totalGCTime += collectionTime;
}
}
return totalGCTime;
}
private static synchronized void collectGarbage() { private static synchronized void collectGarbage() {
Runtime runtime = Runtime.getRuntime(); Runtime runtime = Runtime.getRuntime();
long total = runtime.totalMemory(); long total = runtime.totalMemory();
......
...@@ -23,6 +23,7 @@ import java.util.concurrent.atomic.AtomicInteger; ...@@ -23,6 +23,7 @@ import java.util.concurrent.atomic.AtomicInteger;
import org.h2.test.TestBase; import org.h2.test.TestBase;
import org.h2.tools.Server; import org.h2.tools.Server;
import org.h2.util.StringUtils; import org.h2.util.StringUtils;
import org.h2.util.Utils;
/** /**
* Represents a database in the benchmark test application. * Represents a database in the benchmark test application.
...@@ -37,12 +38,14 @@ class Database { ...@@ -37,12 +38,14 @@ class Database {
private final ArrayList<String[]> replace = new ArrayList<>(); private final ArrayList<String[]> replace = new ArrayList<>();
private String currentAction; private String currentAction;
private long startTimeNs; private long startTimeNs;
private long initialGCTime;
private Connection conn; private Connection conn;
private Statement stat; private Statement stat;
private long lastTrace; private long lastTrace;
private final Random random = new Random(1); private final Random random = new Random(1);
private final ArrayList<Object[]> results = new ArrayList<>(); private final ArrayList<Object[]> results = new ArrayList<>();
private int totalTime; private int totalTime;
private int totalGCTime;
private final AtomicInteger executedStatements = new AtomicInteger(0); private final AtomicInteger executedStatements = new AtomicInteger(0);
private int threadCount; private int threadCount;
...@@ -68,6 +71,15 @@ class Database { ...@@ -68,6 +71,15 @@ class Database {
return totalTime; return totalTime;
} }
/**
* Get the total measured GC time.
*
* @return the time in milliseconds
*/
int getTotalGCTime() {
return totalGCTime;
}
/** /**
* Get the result array. * Get the result array.
* *
...@@ -272,6 +284,7 @@ class Database { ...@@ -272,6 +284,7 @@ class Database {
void start(Bench bench, String action) { void start(Bench bench, String action) {
this.currentAction = bench.getName() + ": " + action; this.currentAction = bench.getName() + ": " + action;
this.startTimeNs = System.nanoTime(); this.startTimeNs = System.nanoTime();
this.initialGCTime = Utils.getGarbageCollectionTime();
} }
/** /**
...@@ -280,9 +293,11 @@ class Database { ...@@ -280,9 +293,11 @@ class Database {
*/ */
void end() { void end() {
long time = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startTimeNs); long time = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startTimeNs);
long gcCollectionTime = Utils.getGarbageCollectionTime() - initialGCTime;
log(currentAction, "ms", (int) time); log(currentAction, "ms", (int) time);
if (test.isCollect()) { if (test.isCollect()) {
totalTime += time; totalTime += time;
totalGCTime += gcCollectionTime;
} }
} }
......
...@@ -149,17 +149,17 @@ public class TestPerformance implements Database.DatabaseTest { ...@@ -149,17 +149,17 @@ public class TestPerformance implements Database.DatabaseTest {
writer = new PrintWriter(new FileWriter(out)); writer = new PrintWriter(new FileWriter(out));
ResultSet rs = stat.executeQuery( ResultSet rs = stat.executeQuery(
"CALL '<table><tr><th>Test Case</th><th>Unit</th>' " + "CALL '<table><tr><th>Test Case</th><th>Unit</th>' " +
"|| SELECT GROUP_CONCAT('<th>' || DB || '</th>' " + "|| (SELECT GROUP_CONCAT('<th>' || DB || '</th>' " +
"ORDER BY DBID SEPARATOR '') FROM " + "ORDER BY DBID SEPARATOR '') FROM " +
"(SELECT DISTINCT DBID, DB FROM RESULTS)" + "(SELECT DISTINCT DBID, DB FROM RESULTS))" +
"|| '</tr>' || CHAR(10) " + "|| '</tr>' || CHAR(10) " +
"|| SELECT GROUP_CONCAT('<tr><td>' || TEST || " + "|| (SELECT GROUP_CONCAT('<tr><td>' || TEST || " +
"'</td><td>' || UNIT || '</td>' || ( " + "'</td><td>' || UNIT || '</td>' || ( " +
"SELECT GROUP_CONCAT('<td>' || RESULT || '</td>' " + "SELECT GROUP_CONCAT('<td>' || RESULT || '</td>' " +
"ORDER BY DBID SEPARATOR '') FROM RESULTS R2 WHERE " + "ORDER BY DBID SEPARATOR '') FROM RESULTS R2 WHERE " +
"R2.TESTID = R1.TESTID) || '</tr>' " + "R2.TESTID = R1.TESTID) || '</tr>' " +
"ORDER BY TESTID SEPARATOR CHAR(10)) FROM " + "ORDER BY TESTID SEPARATOR CHAR(10)) FROM " +
"(SELECT DISTINCT TESTID, TEST, UNIT FROM RESULTS) R1" + "(SELECT DISTINCT TESTID, TEST, UNIT FROM RESULTS) R1)" +
"|| '</table>'" "|| '</table>'"
); );
rs.next(); rs.next();
...@@ -243,6 +243,7 @@ public class TestPerformance implements Database.DatabaseTest { ...@@ -243,6 +243,7 @@ public class TestPerformance implements Database.DatabaseTest {
int statPerSec = (int) (db.getExecutedStatements() * 1000L / db.getTotalTime()); int statPerSec = (int) (db.getExecutedStatements() * 1000L / db.getTotalTime());
db.log("Statements per second", "#", statPerSec); db.log("Statements per second", "#", statPerSec);
System.out.println("Statements per second: " + statPerSec); System.out.println("Statements per second: " + statPerSec);
System.out.println("GC overhead: " + (100 * db.getTotalGCTime() / db.getTotalTime()) + "%");
collect = false; collect = false;
db.stopServer(); db.stopServer();
} }
......
...@@ -193,6 +193,7 @@ public class TestScalability implements Database.DatabaseTest { ...@@ -193,6 +193,7 @@ public class TestScalability implements Database.DatabaseTest {
1000L / db.getTotalTime()); 1000L / db.getTotalTime());
db.log("Statements per second", "#", statPerSec); db.log("Statements per second", "#", statPerSec);
System.out.println("Statements per second: " + statPerSec); System.out.println("Statements per second: " + statPerSec);
System.out.println("GC overhead: " + (100 * db.getTotalGCTime() / db.getTotalTime()) + "%");
collect = false; collect = false;
db.stopServer(); db.stopServer();
} }
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论