Short summary:
Escape analysis is not enabled by default in JDK 6, and it’s available only in server JVM
Thus in order to enable Escape analysis, following parameters for java are required:
[code]
java -server -XX:+DoEscapeAnalysis
[/code]
So lets run run the test from the references…
Test Program
[code lang=”java”]
package org.kari.test;
public class LockTest {
// 20 million .
private static final int MAX = 20000000;
public static void main(String[] args)
throws InterruptedException
{
// warm up the method cache
concatBuffer(”Josh”, ”James”, ”Duke”);
concatBuilder(”Josh”, ”James”, ”Duke”);
System.gc();
Thread.sleep(1000);
long start = System.currentTimeMillis();
for (int i = 0; i < MAX; i++) {
concatBuffer("Josh", "James", "Duke");
}
long bufferCost = System.currentTimeMillis() - start;
System.out.println("StringBuffer: " + bufferCost + " ms.");
System.gc();
Thread.sleep(1000);
start = System.currentTimeMillis();
for (int i = 0; i < MAX; i++) {
concatBuilder("Josh", "James", "Duke");
}
long builderCost = System.currentTimeMillis() - start;
System.out.println("StringBuilder: " + builderCost + " ms.");
System.out.println("Thread safety overhead of StringBuffer: "
+ ((bufferCost * 10000 / (builderCost * 100)) - 100) + "%n");
}
public static String concatBuffer(String s1, String s2, String s3) {
StringBuffer sb = new StringBuffer();
sb.append(s1);
sb.append(s2);
sb.append(s3);
return sb.toString();
}
public static String concatBuilder(String s1, String s2, String s3) {
StringBuilder sb = new StringBuilder();
sb.append(s1);
sb.append(s2);
sb.append(s3);
return sb.toString();
}
}
[/code]
Test script:
[code]
CP=”-cp bin”
MAIN=”org.kari.test.LockTest”
# 1
ARGS=”-server -XX:-DoEscapeAnalysis -XX:-EliminateLocks -XX:-UseBiasedLocking”
echo ””
echo ”TEST: $ARGS”
java $CP $ARGS $MAIN
# 2
ARGS=”-server -XX:+DoEscapeAnalysis -XX:-EliminateLocks -XX:-UseBiasedLocking”
echo ””
echo ”TEST: $ARGS”
java $CP $ARGS $MAIN
# 3
ARGS=”-server -XX:-DoEscapeAnalysis -XX:+EliminateLocks -XX:-UseBiasedLocking”
echo ””
echo ”TEST: $ARGS”
java $CP $ARGS $MAIN
# 4
ARGS=”-server -XX:-DoEscapeAnalysis -XX:-EliminateLocks -XX:+UseBiasedLocking”
echo ””
echo ”TEST: $ARGS”
java $CP $ARGS $MAIN
# 5
ARGS=”-server -XX:-DoEscapeAnalysis -XX:+EliminateLocks -XX:+UseBiasedLocking”
echo ””
echo ”TEST: $ARGS”
java $CP $ARGS $MAIN
# 6
ARGS=”-server -XX:+DoEscapeAnalysis -XX:+EliminateLocks -XX:+UseBiasedLocking”
echo ””
echo ”TEST: $ARGS”
java $CP $ARGS $MAIN
# 7
ARGS=”-server”
echo ””
echo ”TEST: $ARGS”
java $CP $ARGS $MAIN
# 8
ARGS=”-client”
echo ””
echo ”TEST: $ARGS”
java $CP $ARGS $MAIN
[/code]
Results
[code]
Picked up _JAVA_OPTIONS: -Xverify:none -Dsun.java2d.opengl=true
StringBuffer: 4854 ms.
StringBuilder: 3905 ms.
Thread safety overhead of StringBuffer: 24%n
TEST: -server -XX:+DoEscapeAnalysis -XX:-EliminateLocks -XX:-UseBiasedLocking
StringBuffer: 4850 ms.
StringBuilder: 4222 ms.
Thread safety overhead of StringBuffer: 14%n
TEST: -server -XX:-DoEscapeAnalysis -XX:+EliminateLocks -XX:-UseBiasedLocking
StringBuffer: 4598 ms.
StringBuilder: 4509 ms.
Thread safety overhead of StringBuffer: 1%n
TEST: -server -XX:-DoEscapeAnalysis -XX:-EliminateLocks -XX:+UseBiasedLocking
StringBuffer: 4679 ms.
StringBuilder: 3940 ms.
Thread safety overhead of StringBuffer: 18%n
TEST: -server -XX:-DoEscapeAnalysis -XX:+EliminateLocks -XX:+UseBiasedLocking
StringBuffer: 4835 ms.
StringBuilder: 4268 ms.
Thread safety overhead of StringBuffer: 13%n
TEST: -server -XX:+DoEscapeAnalysis -XX:+EliminateLocks -XX:+UseBiasedLocking
StringBuffer: 4989 ms.
StringBuilder: 4397 ms.
Thread safety overhead of StringBuffer: 13%n
TEST: -server
StringBuffer: 4389 ms.
StringBuilder: 3969 ms.
Thread safety overhead of StringBuffer: 10%n
TEST: -client
StringBuffer: 6441 ms.
StringBuilder: 5690 ms.
Thread safety overhead of StringBuffer: 13%n
[/code]
NOTE: I’ve following global java options in use in my system
[code]
export _JAVA_OPTIONS=”-Xverify:none -Dsun.java2d.opengl=true”
[/code]
References:
Did escape analysis escape from Java 6?