2013-07-30 3 views
1

У меня есть каталог pathpath, содержащий около 30 банок. В моем простом консольном приложении я создаю URLClassLoader, где я инициализирую его списком URL s, указывающим на все эти банки.URLClassLoader slow под Tomcat

URL[] urls = new URL[] { 
    new URL("jar:file:/D:/Work/temp/jars/antlr-2.7.7.jar!/"), 
    new URL("jar:file:/D:/Work/temp/jars/aopalliance-1.0.jar!/"), 
    new URL("jar:file:/D:/Work/temp/jars/c3p0-0.9.1.jar!/"), 
    ... 
} 
URLClassLoader cl = new URLClassLoader(urls, getClass().getClassLoader()); 
Class<?> c = cl.loadClass(...); 
etc... 

Как это все работает нормально, принимая несколько миллисекунд, чтобы загрузить один класс от моего URLClassLoader.

Теперь я беру этот фрагмент кода и запускаю его под Tomcat, например. запускается при простом веб-запросе внутри сервлета doGet(). Удивительно, что время, затрачиваемое на загрузку среднего класса, увеличивается в 10-15 раз, делая все время инициализации неприемлемым. Вопрос касается как минимум версий Tomcat 6 и 7.

Любые идеи?

ответ

0

Это абсолютно глупо, но проблема ушла после того, как я перезагрузил мою машину :) Я бегу Windows 7, Oracle JDK 1.6/1.7, Tomcat 6/7, проблема сохраняется для любой комбинации эти. Профилировщик показывал мне, что это sun.net.www.protocol.jar.URLJarFile's <init>, который замедлял весь материал. Вероятно, что-то пошло не так с кешем банки, так что ненужная инициализация выполняется для каждого класса, запрошенного из банки.

Update: Я нашел, как решить проблему с классом нагрузки быть настолько медленным и становится еще медленнее до тех пор, пока вы не перезагрузите машину. Вместо того чтобы использовать

new URL("jar:file:/D:/Work/temp/jars/antlr-2.7.7.jar!/") 

Я попытался

new URL("file:/D:/Work/temp/jars/antlr-2.7.7.jar") 

URLClassloader обрабатывает должным образом этот вид URL, как банки даже без протокола «банка» уточняется. Однако это резко увеличило производительность! Тем не менее, я не знаю точной причины такого поведения.

0

Пробег: new URLClassLoader(urls);. Это улучшает производительность?

Погрузчики классов Common и WebappX могут влиять на производительность загрузки класса. Дополнительную информацию о загрузчике классов Tomcat см. В следующей ссылке.

http://tomcat.apache.org/tomcat-7.0-doc/class-loader-howto.html

+0

Нет, это не так. Это повлияет только на значение родительского загрузчика классов, которое будет системным загрузчиком классов в вашем случае, но это 'findClass()', которое занимает так много времени, поэтому родительский элемент не имеет значения. Другое уведомление: когда я перемещаю все банки в/WEB-INF/lib, они мгновенно загружаются WebappClassLoader, как и в консольном приложении. Я вижу, что, несмотря на то, что WebappClassLoader расширяет URLClassLoader, он не использует свой механизм для загрузки классов, вместо этого использует свой собственный. Но я не могу различить принципиальную разницу. –

+0

Другое наблюдение: длинные пути файловой системы (глубина 10 или более) к банкам принимают 'URLClassLoader' примерно в два раза больше, чем загружать классы по сравнению с короткими путями. –

Смежные вопросы