Я наблюдаю снижение производительности на 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 с чтобы запустить этот код. В обоих случаях я запускаю код, когда загрузка процессора очень низкая (скажем, 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 , адрес = 8787, сервер = y, приостановить = n
Я использую Linux 2.6.32-279.11.1.el6.x86_64 с версией java "1.7.0_07".
Это в приложении J2EE. Я использую CDI, поэтому у меня есть кнопка на странице JSF, которая будет вызывать метод "continue" в компоненте @RequestScoped PerformanceTest. Я развертываю его как отдельный файл war, и даже если я отменю развертывание других приложений, это не повлияет на производительность.
Это виртуальная машина, которая разделяет ЦП с другой машиной, но она ничего не потребляет.
Вот еще одно наблюдение: когда сервер запускается заново и я запускаю пузырьковую сортировку, он использует 100% одного ядра процессора. Он никогда не переключается на другое ядро и не снижает коэффициент использования ниже 95%. Однако через некоторое время сервер работает, и я испытываю проблемы с производительностью, описанный выше метод использует ядро ЦП обычно на 100%, однако я только что узнал из htop, что эта задача очень часто переключается на другие ядра. То есть вначале он работает на ядре № 1, скажем, через 2 секунды он работает на № 5, затем, скажем, через 2 секунды № 8 и т. Д. Кроме того, использование ядра не поддерживается на 100%, а иногда падает до 80%. или даже ниже.
Для сервера после нового запуска, даже если я моделирую нагрузку, он никогда не переключает задачу на другое ядро.
Это может быть связано со следующей ошибкой 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.
Эта проблема была решена путем обновления до JBoss 7.1.4-SNAPSHOT. Посмотрите эту ветку: https://community.jboss.org/thread/213546?start=0&tstart=0
Я считаю, что метод, который вы используете 100000 раз для одного теста (Math.random ()), не дает одинаковый набор чисел в разных тестах, поэтому изменение порядка занимает разное время. Вы должны использовать java.util.Random для создания нового псевдослучайного генератора в начале каждого теста (который будет начинаться с того же начального числа) и использовать nextDouble () для получения нового числа; вы можете попробовать разные тесты с разными семенами (setSeed (...)).