Вызов System.gc (), вызывающий потерю данных в JSP - PullRequest
0 голосов
/ 04 августа 2010

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

В разделе кода JSP, который обрабатывает создание объектов сеанса, я добавил следующий код:

System.gc();
long orgHeap = Runtime.getRuntime().freeMemory();

... create session variables ...

System.gc();
log.info("Heap delta: " + (Runtime.getRuntime().freeMemory() - orgHeap));

Что меня удивило, так это то, что добавление System.gc () ломает приложение. Это больше не работает, так как некоторые объекты теряются (или так кажется). Значения, которые были инициализированы, являются нулевыми. Когда вызовы gc () удалены, приложение работает нормально. gc () должен удалять только те объекты, которые были помечены для удаления - верно?

У кого-нибудь еще были подобные проблемы?

Ответы [ 2 ]

2 голосов
/ 04 августа 2010

Единственный случай, который я могу вспомнить, где это может произойти, как вы описываете, это если вы используете WeakReference s (или истек срок действия SoftReference s, которые в целом похожи в это ситуация) для ссылки на объекты, которые вы все еще хотите сохранить. Объекты, которые могут попасть в состояние, в котором они собирают в состоянии GC; но пока он действительно не запустится, вы все равно сможете связаться с ними по ссылкам. Вызов System.gc(), даже если у него нет гарантированной семантики, может привести к тому, что сборщик запустится и соберет все эти слабо достижимые объекты.

Это кажется маловероятным, потому что

  1. Случайное использование WeakReferences для сильно достижимых объектов не кажется легкой ошибкой. Даже если вы пользуетесь библиотеками, мне трудно вспомнить случай, когда вы могли бы в итоге по ошибке использовать слабые ссылки.
  2. Если это произойдет, поведение приложения в любом случае будет неопределенным. Сборка мусора может произойти в любое время, поэтому вы, вероятно, увидите несогласованное поведение без вызова System.gc (). В любом случае у вас всегда будет какой-то фрагмент кода, который выполняется сразу после коллекции, и вы не сможете найти его референтный объект.
  3. System.gc () теоретически ничего не делает, поэтому не должно вызывать это.

Этот последний пункт важен - почему вы все равно вызываете System.gc () , когда это почти всегда контрпродуктивно для вызова? Я не верю, что у вас есть законная необходимость называть это, она не делает ничего, на что вы можете положиться, и, очевидно, она нарушает ваше приложение.

Так что, если ваше приложение работает нормально без вызова, просто прекратите его делать.

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

РЕДАКТИРОВАТЬ: Другой возможной причиной этого может быть простое время. Звонок System.gc(), вероятно, займет немалое количество времени. В течение этого периода другие потоки могут прогрессировать и изменять состояние так, как этого не ожидает поток GCing. Следовательно, когда он возвращается из вызова, состояние мира нарушает его ожидания и, следовательно, возникают логические ошибки. Опять же, это всего лишь предположение, но оно более правдоподобно, чем WeakReference.

0 голосов
/ 04 августа 2010

Сборка мусора никогда не удалит живые объекты, поэтому я думаю, что ваша проблема в другом месте.

Поскольку вы утверждаете, что это под нагрузкой - «частота попаданий высока» - это может быть случай неправильного использования EJB,где вы ожидаете, что что-то произойдет, потому что это происходит при низкой нагрузке (например, повторное получение одного и того же EJB при запросе этого), но это изменение происходит при высокой нагрузке (кто-то другой получил этот EJB, вы получили другой).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...