【发布时间】:2015-07-23 11:50:10
【问题描述】:
使用AtomicLong.incrementAndGet的方法测试JDK 7和JDK 8的性能差异,测试数据显示JDK7的性能优于JDK 8。为什么JDK7的性能优于JDK 8? JDK 8 性能不佳的原因是什么?
测试报告:
<table border="1">
<thead>
<tr>
<th>The number of threads</th>
<th>JDK7(Unit:Milliseconds)</th>
<th>JDK8(Unit:Milliseconds)</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>441351</td>
<td>444246</td>
</tr>
<tr>
<td>4</td>
<td>245872</td>
<td>248655</td>
</tr>
<tr>
<td>8</td>
<td>240513</td>
<td>245395</td>
</tr>
<tr>
<td>16</td>
<td>275445</td>
<td>279481</td>
</tr>
</tbody>
</table>
系统环境:
CPU:Intel(R) Xeon(R) CPU E5620 @ 2.40GHz 2.40GHz(两个处理器)
内存:8.00GB
系统:Windows Server 2008 R2 标准版
JDK版本信息:
JDK7:“1.7.0_75”
JDK8:“1.8.0_45”
JVM 参数:
JDK 7:
设置JVM_OPT=-Xms1024m -Xmx1024m -Xmn256m -XX:SurvivorRatio=8 -XX:PermSize=128m -XX:MaxPermSize=256m -XX:+UseConcMarkSweepGC -XX:+UseParNewGC SET JVM_OPT=%JVM_OPT% -XX:+DisableExplicitGC SET JVM_OPT=%JVM_OPT% -XX:+UseCMSCompactAtFullCollection -XX:CMSFullGCsBeforeCompaction=0 设置 JVM_OPT=%JVM_OPT% -Dthread_count=16 设置 JVM_OPT=%JVM_OPT% -Dsize=5 设置 JVM_OPT=%JVM_OPT% -Dmax=300000000
JDK 8:
设置JVM_OPT=-Xms1024m -Xmx1024m -Xmn256m -XX:SurvivorRatio=8 -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=256m -XX:+UseConcMarkSweepGC -XX:+UseParNewGC SET JVM_OPT=%JVM_OPT% -XX:+DisableExplicitGC SET JVM_OPT=%JVM_OPT% -XX:+UseFastAccessorMethods -XX:+CMSClassUnloadingEnabled - XX:+CMSParallelRemarkEnabled SET JVM_OPT=%JVM_OPT% -XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=62 设置 JVM_OPT=%JVM_OPT% -Dthread_count=16 设置 JVM_OPT=%JVM_OPT% -Dsize=5 设置 JVM_OPT=%JVM_OPT% -Dmax= 300000000
测试代码:
public class Main {
private static final int K_SIZE = 1024;
private static final long MAX = 300_000_000L;
public static void main(String[] args) {
int threadCount = Integer.getInteger("thread_count", 4);
final int size = Integer.getInteger("size", 5);
final long max = Long.getLong("max", MAX);
final AtomicLong count = new AtomicLong();
final CountDownLatch beginLatch = new CountDownLatch(1);
final CountDownLatch endLatch = new CountDownLatch(threadCount);
ExecutorService executor = Executors.newFixedThreadPool(threadCount);
for (int i = 0; i < threadCount; i++) {
executor.execute(new Runnable() {
ConcurrentMap<Long, Long> map = new ConcurrentHashMap<Long, Long>();
@Override
public void run() {
try {
beginLatch.await();
byte[] data = null;
while (!Thread.currentThread().isInterrupted()) {
data = new byte[size * K_SIZE];
long current = count.incrementAndGet();
map.put(current, current);
data[0] = (byte) current;
if (current >= max) {
endLatch.countDown();
break;
} else if ((current % 1000) == 0) {
map.clear();
}
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
});
}
long startTime = System.currentTimeMillis();
beginLatch.countDown();
try {
endLatch.await();
long endTime = System.currentTimeMillis();
System.out.println(endTime - startTime);
} catch (InterruptedException e) {
}
executor.shutdown();
}
}
【问题讨论】:
-
为什么重要?它证明了什么?这真的是您应用程序中的关键路径吗?因为我觉得这很难相信。
-
我建议您在尝试查看小操作的行为之前删除所有其他冗余且非常慢的操作,否则您正在执行的大操作很可能是问题的真实案例.
标签: java