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