我在 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 也遇到了类似的问题。将 增加到ReservedCodeCacheSize
并256m
设置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(...))。