Bezdepbonusu7Программирование: статьи и ответы

Вопрос

Коллекции Java и сборщик мусора

Автор вопроса: Anth0Ответов: 3

Небольшой вопрос относительно производительности в веб-приложении Java.

Предположим, у меня есть List<Rubrique> listRubriques с десятью Rubrique объектами.

Rubrique содержит один список продуктов (List<product> listProducts) и один список клиентов (List<Client> listClients).

Что именно произойдет в памяти, если я сделаю это:

listRubriques.clear(); listRubriques = null;

Я считаю, что, поскольку listRubriques пусто, все мои объекты, на которые ранее ссылался этот список (включая listProducts и listClients), довольно скоро будут собраны мусором. Но поскольку Коллекция на Java немного сложна, и поскольку у меня довольно проблемы с производительностью с моим приложением, я задаю вопрос :)

edit: предположим теперь, что мой объект Client содержит List<Client>. Следовательно, у меня есть своего рода круговая ссылка между моими объектами. Что произойдет, если мой listRubrique установлен на null? На этот раз я считаю, что мои объекты Client станут "недоступными" и могут вызвать утечку памяти?

javacollectionsperformancegarbage-collection

Ответы

Ответ 1 · рейтинг 15 · Mnementh

Фактическая реализация Sun для Java время от времени копирует все связанные / живые объекты. Пространство, из которого было скопировано, можно затем снова использовать для выделения памяти.

Тем не менее, ваши примеры действительно ухудшают производительность. listRubriques.clear() не нужен (за исключением того, что у вас есть еще какая-то ссылка на него), потому что все, на что ссылается listRubrique, является мусором в тот момент, когда listRubriques больше не ссылается. listRubriques = null также может оказаться ненужным, если переменная listRubriques впоследствии выйдет за пределы области видимости (возможно, потому, что это локальная переменная и на этом заканчивается метод).

Не только вызов clear не нужен, поскольку clear обращается к памяти объекта, который впоследствии больше не используется, осуществляется доступ к объекту, и современные процессоры помещают его в свой кеш. Таким образом, мертвый объект явно попадает в кэш процессора - некоторые, возможно, более полезные данные будут перезаписаны для этой операции.

Эта статья является хорошим справочником для получения дополнительной информации о Java Уборщик мусора.

РЕДАКТИРОВАТЬ: чтобы отреагировать на изменение в вопросе: сборщик мусора (по крайней мере, реализация, используемая Sun) запускается с некоторых корневых ссылок и копирует все объекты, к которым он может добраться из этих ссылок, и на которые есть ссылки. скопированными объектами. Таким образом, ваши объекты с круговыми ссылками являются мусором, поскольку на них не указывает "внешняя" ссылка, и память будет восстановлена ​​при сборке мусора.

Ответ 2 · рейтинг 4 · Asaph

Если у вас есть:

listRubriques = null;

и нет других объектов, содержащих ссылки на listRubriques или содержащиеся в нем объекты, он имеет право на сборку мусора. Но нет никакой гарантии, когда JVM действительно запустит сборку мусора и освободит память. Вы можете позвонить:

System.gc();

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

Также имея

listRubriques.clear();

перед установкой listRubriques на null нет необходимости.

РЕДАКТИРОВАТЬ: чтобы ответить на ваш вопрос о циклических ссылках, JVM достаточно умен, чтобы выяснить, что весь граф объектов отключен от любого активно работающего кода, и JVM правильно определит, что все они имеют право на сборку мусора. . Это всегда было правдой, даже в старые плохие времена подсчета ссылок. Современные JVM просто быстрее и эффективнее. Но они не собирают мусор больше, чем старые JVM.

Ответ 3 · рейтинг 1 · jarnbjo

"Довольно скоро" - это довольно расплывчатая спецификация, но сборщик мусора, вероятно, не так быстр, как вы ожидаете. Когда на самом деле будут собраны объекты, во многом зависит от конфигурации GC и загрузки вашего сервера, но это может занять некоторое время, и если ваша виртуальная машина имеет достаточно доступной кучи и других вещей, которые нужно сделать, объекты не будут собраны "довольно скоро" .

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

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы