В веб-приложении каждая задача выполняется в виде запроса и ответа.
Программирование на стороне клиента - это HTML-код с Java-скриптом и его фреймворками, библиотеки выполняются в Internet Explorer, Mozilla, Chrome-браузерах. В сценарии Java-сценария серверные сервлеты программирования выполняются в Tomcat, web-логике, j боссе, WebSphere severs
Единственный способ, которым может быть выгружен класс, - это использование класса Loadload для сбора мусора. Это означает, что ссылки на каждый отдельный класс и сам загрузчик классов должны идти по пути dodo.
Одним из возможных решений вашей проблемы является наличие Classloader для каждого файла jar и Classloader для каждого AppServers, который делегирует фактическую загрузку классов конкретным загрузчикам классов Jar. Таким образом, вы можете указать разные версии файла jar для каждого сервера приложений.
Это, однако, не тривиально. Платформа OSGi стремится сделать именно это, поскольку каждый комплект имеет другой загрузчик классов, а зависимости решаются платформой. Может быть, хорошим решением было бы взглянуть на него.
Если вы не хотите использовать OSGI, одной из возможных реализаций может быть использование одного экземпляра класса JarClassloader для каждый файл JAR.
И создайте новый класс MultiClassloader, расширяющий Classloader. Этот класс внутренне имел бы массив (или список) JarClassloaders, а в методе defineClass () выполнял бы итерацию по всем внутренним загрузчикам классов до тех пор, пока не будет найдено определение или исключение NoClassDefFoundException. Для добавления новых классов JarClassloaders в класс может быть предоставлено несколько методов доступа. Существует несколько возможных реализаций в сети для MultiClassLoader, поэтому вам даже не нужно писать свои собственные.
Если вы инициируете MultiClassloader для каждого подключения к серверу, в принципе, возможно, что каждый сервер использует другую версию того же класса.
Я использовал идею MultiClassloader в проекте, где классы, содержащие пользовательские скрипты, должны были быть загружены и выгружены из памяти, и это сработало достаточно хорошо.
Если вы живете, если класс разгрузки работал в JConsole или что-то еще, попробуйте добавить java.lang.System.gc()
в конец логики разгрузки вашего класса. Он явно запускает сборщик мусора.
Да, есть способы загрузить классы и «разгрузить» их позже. Хитрость заключается в том, чтобы реализовать свой собственный загрузчик классов, который находится между загрузчиком класса высокого уровня (загрузчик класса System) и загрузчиками классов серверов приложений, и надеяться, что загрузчики классов сервера приложений делегируют загрузку классов в верхние загрузчики .
Класс определяется его пакетом, его именем и загружаемым им загрузчиком классов. Запрограммируйте загрузчик классов «прокси», который является первым, который загружается при запуске JVM. Рабочий процесс:
java.x
и sun.x
системному загрузчику классов (эти не должны загружаться через любой другой загрузчик классов, чем системный загрузчик классов). Выполнено прямо там не должно быть ClassCastException или LinkageError и т. д.
Для получения дополнительной информации о иерархиях загрузчика классов (да, это именно то, что вы здесь реализуете;) смотрите «Сервер Java Programming "Теда Ньюварда - эта книга помогла мне реализовать что-то очень похожее на то, что вы хотите.
ClassLoader
для каждого класса слишком много, один ClassLoader
на JAR имеет смысл. Может быть более конкретным о том, как принудительно загрузить класс в предлагаемой схеме? Например. как я могу гарантировать, что экземпляры классов, загружаемых ClassLoaderA, не передаются экземплярами, загружаемыми ClassLoaderB?
– dma_k
20 January 2011 в 01:23
Вы можете выгрузить ClassLoader, но вы не можете выгружать определенные классы. Более конкретно, вы не можете выгружать классы, созданные в ClassLoader, который не находится под вашим контролем.
Если возможно, я предлагаю использовать свой собственный ClassLoader, чтобы вы могли его выгружать.
Я написал пользовательский загрузчик классов, из которого можно разгрузить отдельные классы без GCing загрузчика классов. Jar Class Loader
JarClassLoader
для каждого загруженного файла jar, вы можете называть его getLoadedClasses()
, затем перебирать его и выгружать.
– Ercksen
30 November 2015 в 18:54
Погрузчики классов могут быть сложной проблемой. Вы можете столкнуться с проблемами, если используете несколько загрузчиков классов и не имеете четкого и строгого определения своих взаимодействий. Я думаю, чтобы действительно иметь возможность выгружать класс, который вы собираетесь удалить, нужно удалить все ссылки на какие-либо классы (и их экземпляры), которые вы пытаетесь выгрузить.
Большинство людей, которым необходимо выполнить этот тип предмет в конечном итоге используя OSGi . OSGi действительно мощный и удивительно легкий и простой в использовании,
Классы имеют скрытую ссылку на экземпляр ClassLoader и наоборот. Они собирают мусор, как с объектами Java. Не удаляя интерфейс инструмента или аналогичный, вы не можете удалить отдельные классы.
Как всегда вы можете получить утечки памяти. Любая сильная ссылка на один из ваших классов или загрузчик классов будет утечка всего. Это происходит, например, с реализациями Sun ThreadLocal, java.sql.DriverManager и java.beans.