【问题标题】:The Performance Difference Between The JDK 7 And JDK 8 Use AtomicLong.incrementAndGetJDK 7 和 JDK 8 使用 AtomicLong.incrementAndGet 的性能差异
【发布时间】: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


【解决方案1】:

您展示的性能差异小于 1%。这太小了,以至于除了一小部分应用程序之外,其他所有应用程序都无关紧要。即使使用高分辨率分析工具,通常也很难确定导致此类微不足道的性能变化的明确原因。在 1.7 和 1.8 之间有如此多的新功能,这可能是由多种原因造成的。

暂时纯粹是推测性的,1.7 和 1.8 之间有数百个错误修复。应对边缘条件的额外错误检查很容易导致轻微的性能下降。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多