Как я могу провести модульное тестирование GC? - PullRequest
5 голосов
/ 09 января 2012

Для проекта нам нужен способ запуска пользовательских сценариев, которые могут поставляться с вложенными файлами JAR с дополнительными классами.

Какие у меня варианты, когда я хочу написать пару тестов, чтобы убедиться, что обычный скрипт не оставляет ничего висящего?

Мне нужно знать: все ли классы из подключенных JAR-файлов "выгружены"?

Примечание: я не ищу 100% суперводонепроницаемое решение, которое работает во всех версиях Java от 1.0 до 7. Сейчас мне просто нужно быть лучше, чем "Я понятия не имею".

Ответы [ 4 ]

3 голосов
/ 09 января 2012

Вероятно, лучший вариант - убедиться, что загруженные файлы jar загружены определенным загрузчиком классов, а затем удалить этот загрузчик классов (после удаления всех объектов).

Что касается модульного тестирования выгрузки, если вы выберете эту опцию, вам нужно расширить свою среду тестирования и настроенные загрузчики классов, чтобы иметь флаг «Создать загрузчик классов по требованию». Затем вы загружаете класс один раз с включенным флагом, сбрасываете загрузчик классов и пытаетесь загрузить класс снова с отключенным флагом. Если класс действительно недоступен, вторая попытка должна вызвать исключение для класса, не найденного. Затем вы оборачиваете свои модульные тесты для прохождения, если они попадают в исключение, и не выполняются, если им удается попасть в линию после второй попытки загрузки.

Если вы склонны использовать больше, чем просто инструменты Java, контейнер OSGi может быть рассмотрен. Большинство установленных реализаций OSGi-контейнера явно тестируют выгрузку классов.

3 голосов
/ 09 января 2012

Я бы не стал тестировать этот модуль.Вместо этого я бы запустил JVM с -XX: -TraceClassUnloading и посмотрел, отображаются ли соответствующие классы в выводе трассировки.

2 голосов
/ 09 января 2012

Похоже, что вы хотите проверить, что скрипты шлангов не имеют утечки загрузчика классов .

Чтобы сделать это, я бы создал WeakReference для ClassLoader, использованного для загрузки этого JAR, затем запустил скрипт, затем вызвал System.gc(), а затем assertNull(reference.get())

1 голос
/ 09 января 2012

Это полностью зависит от того, как вы разрешите выполнение сценариев.Имеют ли они доступ к классам остальной части приложения?

Типичный способ утечки памяти в Java - иметь статическую ссылку.Статическая ссылка является статической только в ClassLoader класса, который ее содержит.Таким образом, если вы загружаете свои пользовательские сценарии с помощью ClassLoader, которым вы управляете сами (и вы должны делать это в любом случае), то ссылки (статические или нет) внутри будут пригодны для GC, как только ваш загрузчик классов сам сделает это.

Единственный способ обойти это - добавить ссылку на один из своих объектов в один из ваших.Поэтому вы должны быть очень осторожны с предоставляемым вами API.Другой способ, если бы они сделали статическую ссылку на свой класс в классе из другого ClassLoader.

Я не вижу способа полностью автоматизировать тестирование для этого.Но я полагаю, вы могли бы отслеживать выгрузку класса с помощью любого приличного профилировщика.

...