CPU/JVM/JBoss 7 随着时间的推移而变慢

CPU/JVM/JBoss 7 随着时间的推移而变慢

我在 JBoss 7.1.1 Final 上遇到了性能下降的问题。我编写了一个简单程序来演示此行为。我生成了一个包含 100,000 个随机整数的数组,并对其运行冒泡排序。

   @Model
   public class PerformanceTest {

      public void proceed() {
                long now = System.currentTimeMillis();
                int[] arr = new int[100000];
                for(int i = 0; i < arr.length; i++) {
                          arr[i] = (int) (Math.random() * 200000);
                }
                long now2 = System.currentTimeMillis();
                System.out.println((now2 - now) + "ms took to generate array");
                now = System.currentTimeMillis();
                bubbleSort(arr);
                now2 = System.currentTimeMillis();
                System.out.println((now2 - now) + "ms took to bubblesort array");
      }

      public void bubbleSort(int[] arr) {
                boolean swapped = true;
                int j = 0;
                int tmp;
                while (swapped) {
                          swapped = false;
                          j++;
                          for (int i = 0; i < arr.length - j; i++) {
                                    if (arr[i] > arr[i + 1]) {
                                              tmp = arr[i];
                                              arr[i] = arr[i + 1];
                                              arr[i + 1] = tmp;
                                              swapped = true;
                                    }
                          }
                }
      }

}

在我启动服务器后,运行此代码大约需要 22 秒。运行 JBoss 7.1.1 几天后,需要330 秒运行此代码。在这两种情况下,我都是在 CPU 利用率非常低(例如 1%)时启动代码。知道为什么吗?我使用以下参数运行服务器:

-Xms1280m -Xmx2048m -XX:MaxPermSize=2048m -Djava.net.preferIPv4Stack=true -Dorg.jboss.resolver.warning=true -Dsun.rmi.dgc.client.gcInterval=3600000 -Dsun.rmi.dgc.server.gcInterval=3600000 -Djboss.modules.system.pkgs=org.jboss.byteman -Djava.awt.headless=true -Duser.timezone=UTC -Djboss.server.default.config=standalone-full.xml -Xrunjdwp:transport=dt_socket,address=8787,server=y,suspend=n

我在 Linux 2.6.32-279.11.1.el6.x86_64 上以 java 版本“1.7.0_07”运行它。

它位于 J2EE 应用程序中。我使用 CDI,因此我在 JSF 页面上有一个按钮,它将调用 @RequestScoped 组件 PerformanceTest 上的方法“proceed”。我将其部署为单独的 war 文件,即使我取消部署其他应用程序,也不会改变性能。

它是一个与另一台机器共享 CPU 的虚拟机,但它不消耗任何东西。

这里还有另一个观察结果:当服务器重新启动后,我运行冒泡排序时,它会利用一个处理器核心的 100%。它从不切换到另一个核心或将利用率降至 95% 以下。然而,在服务器运行一段时间后,我遇到了性能问题,上述方法通常利用 CPU 核心 100%,但我刚刚从 htop 发现此任务经常切换到其他核心。也就是说,一开始它在核心 #1 上运行,2 秒后它在 #5 上运行,然后在 #8 上运行,再过 2 秒,等等。此外,核心的利用率不会保持在 100%,有时会降至 80% 甚至更低。

对于全新启动后的服务器,即使我模拟负载,它也永远不会将任务切换到另一个核心。

答案1

它可能与以下 Java 7 CodeCache 错误有关:http://bugs.java.com/view_bug.do?bug_id=8023191

运行几天后,我们遇到了类似的“减速”问题,JBoss 7.1.1 和 Java 7 也遇到了类似的问题。将 增加到ReservedCodeCacheSize256m设置UseCodeCacheFlushing为 可以true解决问题。

您可以使用 JConsole 来监控 CodeCache 的利用率。

答案2

通过升级到 JBoss 7.1.4-SNAPSHOT 解决了此问题。查看此线程:https://community.jboss.org/thread/213546?start=0&tstart=0

答案3

我相信您在一次测试中使用 100000 次的方法 (Math.random()) 不会在不同的测试中产生相同的数字集,因此重新排序需要不同的时间。您应该在每次测试开始时使用 java.util.Random 创建一个新的伪随机生成器(它将以相同的种子开始),并使用 nextDouble() 获取一个新数字;您可以尝试使用不同的种子进行不同的测试 (setSeed(...))。

相关内容