У нас есть контейнер OSGi с множеством продуктов, работающих внутри, один из которых является нашим продуктом.
У нас есть некоторые тесты производительности, и есть такая странная проблема, что при каждом перезагрузке контейнера OSGi для некоторых наших тестов до 400% будет отклоняться производительность.
Через некоторое тестирование и вещей, которые я был в состоянии отслеживать это вниз к этому методу:Отклонения в производительности для небольшого метода
public static Method getMethodForSlotKey(Class<?> cls, String slotKey, String methodType) {
Method[] methods = cls.getMethods();
if (methods != null && methods.length > 0) {
for (Method method : methods) {
String methName = method.getName();
if (methName.startsWith(methodType)) {
IDataAnnotation annot = method.getAnnotation(IDataAnnotation.class);
if (annot != null) {
String annotSlotKey = annot.SlotKey();
if (annotSlotKey != null && annotSlotKey.equals(slotKey)) {
Class<?>[] paramTypes = method.getParameterTypes();
// for now, check length == 1 for setter and 0 for getter.
int len = SET_TXT.equals(methodType) ? 1 : 0;
if (paramTypes != null && paramTypes.length == len) {
return method;
}
}
}
}
}
}
return null;
}
Этот метод в основном делает отражение и сравнение строк.
Теперь, я сделал это, чтобы кэшировать результаты этого метода, и мгновенно наше отклонение снижается до 10-20%. Конечно, этот метод часто называют, так что улучшение улучшается.
По-прежнему я не понимаю, почему не кэшированная версия имеет такое высокое отклонение с той лишь разницей, что перезапуск OSGi/JVM? Что именно может произойти во время перезапуска? Существуют ли какие-либо известные проблемы производительности для разных загрузчиков классов? Возможно ли, что в библиотеках среды OSGi будут загружены в другом порядке между перезапусками?
Я ищу ключ, чтобы это имело смысл.
UPDATE
Оказывается, что этот призыв:
Method[] methods = cls.getMethods();
вызывает отклонение. Я до сих пор не понимаю этого, поэтому, если кто-нибудь сделает это, я буду рад услышать об этом.
Некоторые вызовы, основанные на отражении, повторно скомпилированы и оптимизированы JVM, если функция вызывается 15000 раз. После этого они становятся намного эффективнее. Попытайтесь вызвать свою функцию 15 тысяч раз и посмотреть, повышается ли производительность. Если да, это так. Номер после повторного компиляции кода может быть настроен в JVM, но я не помню имена параметров. Также вы можете установить в JVM для выхода из этих задач повторной компиляции. –
Эй, я не нашел этот вариант, может быть, вы можете вспомнить точное имя? – sveri
http://artiomg.blogspot.hu/2011/10/just-in-time-compiler-jit-in-hotspot.html. Я думаю, вы можете установить количество вызовов функций с помощью -XX: CompileThreshold = XXX и распечатать компиляцию и статистику с помощью «XX: + PrintCompilation» и «-XX: -CITime». Если это ответ, я отвечу на него правильно и возьму щедрость ;-) –