Как напечатать события сбора мусора класса Java? - PullRequest
9 голосов
/ 22 февраля 2009
java version "1.5.0_14"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_14-b03)
Java HotSpot(TM) Server VM (build 1.5.0_14-b03, mixed mode)

Я пытаюсь отладить исключение NullPointerException, которое я получаю за передачу ссылки на статически определенное поле. Если быть более точным, я устанавливаю глобальную переменную для экземпляра рабочей памяти Drools3.

workingMemory.setGlobal("log", workingMemorieslog);

Я предполагаю, что класс, где поле статически определено, является сборщиком мусора. (Получающий класс должен использовать WeakReference или что-то в этом роде, я действительно не знаю)

Как бы вы предложили отладить это? Я думаю, что если бы я мог точно знать, когда GC JVM выгружает класс / экземпляр класса, то я мог бы сузить причину ошибочного поведения. (Если не точное время события, по крайней мере, указание на то, что что-то произошло).

Спасибо, Максим.

Ответы [ 4 ]

10 голосов
/ 22 февраля 2009

Для отслеживания активности GC добавьте это в команду java:

-verbose: дс -XX: + PrintGCTimeStamps -XX: + PrintGCDetails

NPE, который вы получаете, вероятно, вы передаете нулевое значение.

2 голосов
/ 22 февраля 2009

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

1 голос
/ 22 февраля 2009

Оказывается, затмение - главная проблема здесь.

Я объясню:

Я обернул наше веб-приложение в метод main () для проверки производительности. Мы используем много стороннего кода, а именно Apache commons-pool.

Оказывается, у нас было несколько версий фляги, распределенных по проектам (проекты затмения). В моем приложении, использующем эти проекты, был commons-pool-1.3, в другом проекте - commons-pool-1.2.

При загрузке с использованием контейнера сервлета (Tomcat6) загрузчик классов веб-приложений имел первый приоритет, поэтому он всегда загружал версию веб-приложения. Когда я запустил приложение, используя main () eclipse, в нем не очень разумное поведение экспортировал зависимые проекты jar-файлов в -classpath ДО тех, что в текущем проекте.

Конфликт произошел между двумя версиями commons-pool, что вызвало неопределенное поведение - В случае заимствования объекта ИНОГДА решили создать новый объект. Я не заглядывал внутрь кода реализации, я предполагаю, что это как-то связано со статической картой, удерживаемой GenericKeyedObjectPool (проблемный класс). Поскольку новый экземпляр был создан, он действительно содержит нулевую ссылку на упомянутый глобальный объект.

Решение моей удачи было довольно простым, commons-pool используется только моим веб-приложением, поэтому я мог удалить его из всех проектов, на которые есть ссылки, в противном случае, я думаю, я бы просто попытался обновить их все до одной версии. Если бы я не мог сделать то же самое, я действительно не знаю, что бы я сделал. Это очень странное значение затмения по умолчанию.

Спасибо за чтение и помощь.

// пс. 3 дня. Это время, которое я трачу на понимание, что, черт возьми, я сделал неправильно в своем коде замены сервлета. Оказывается, я даже не проблема. : P

0 голосов
/ 22 февраля 2009

Есть ли у вас трассировка стека?

Вы пытались войти в метод setGlobal (если у вас есть код), чтобы увидеть, что происходит?

...