Можно ли форсировать сборку мусора в Java, даже если это сложно сделать? Я знаю , о System.gc();
и , Runtime.gc();
но они только предлагают сделать GC. Как я могу заставить GC?
java
garbage-collection
Роберт Колумбия
источник
источник
Ответы:
Ваш лучший вариант - это вызов,
System.gc()
который просто является подсказкой сборщику мусора о том, что вы хотите, чтобы он делал сбор. Нет никакого способа принудительного и немедленного сбора, поскольку сборщик мусора недетерминирован.источник
non-deterministic == trouble
GC.Collect()
не собирает. В Java этоgc()
делает.Библиотека jlibs имеет хороший служебный класс для сборки мусора . Вы можете форсировать сборку мусора, используя хитрый трюк с объектами WeakReference .
RuntimeUtil.gc () из jlibs:
источник
PhantomReference
с,ReferenceQueue
и вы получите уведомление после завершения, но еще до очистки. Наконец, даже если вы успешно обнаружите, что память для этого объекта была восстановлена, это все равно будет означать очень мало в поколенческом GC, подобном HotSpot. Обычно это совпадает с уборкой молодого поколения.System.gc(); System.gc();
, но было бы интересно узнать, работает ли это когда-либо лучше, чем это. На самом деле, достаточно просто напечатать, сколько раз он звонилSystem.gc()
. Шанс когда-либо достичь 2 довольно мал.Лучший (если не единственный) способ заставить GC - написать пользовательскую JVM. Я считаю, что сборщики мусора являются подключаемыми, так что вы можете просто выбрать одну из доступных реализаций и настроить ее.
Примечание: это не простой ответ.
источник
Используя интерфейс виртуальной машины Java ™ (JVM TI) , функцию
«Принудительно заставит виртуальную машину выполнить сборку мусора». TI JVM является частью архитектуры отладчика платформы JavaTM (JPDA) .
источник
ДА, почти возможно заставить вас вызывать методы в том же порядке, и в то же время это:
даже если один и тот же объект очищает использование этих двух методов одновременно, вынуждает сборщик мусора использовать
finalise()
метод недоступного объекта, освобождая назначенную память и делая то, чтоfinalize()
утверждает метод.ОДНАКО это ужасная практика использования сборщика мусора, потому что его использование может привести к перегрузке программного обеспечения, которая может быть даже хуже, чем к памяти, сборщик мусора имеет свой собственный поток, который невозможно контролировать плюс в зависимости от Алгоритм, используемый gc, может занять больше времени и считается очень неэффективным. Вы должны проверить свое программное обеспечение, если оно хуже с помощью gc, потому что оно определенно сломано, и хорошее решение не должно зависеть от gc.
ПРИМЕЧАНИЕ: просто помните, что это будет работать только в том случае, если в методе finalize нет переназначения объекта, если это произойдет, объект останется в живых и произойдет воскресение, что технически возможно.
источник
gc()
это только подсказка для запуска сборки мусора.runFinalizers()
финализаторы запускаются только на объектах, "которые были найдены как отброшенные". Если gc на самом деле не запускался, таких объектов может не быть ...В документации для OutOfMemoryError он заявляет, что он не будет выброшен, если виртуальная машина не смогла восстановить память после полной сборки мусора. Таким образом, если вы продолжите выделять память до тех пор, пока не получите сообщение об ошибке, вы уже запустите полную сборку мусора.
Предположительно, вопрос, который вы действительно хотели задать, был: «Как я могу восстановить память, которую, как мне кажется, я должен вернуть, путем сбора мусора?»
источник
Чтобы вручную запросить GC (не из System.gc ()):
источник
.gc - кандидат на исключение в будущих выпусках - инженер Sun однажды заметил, что, возможно, менее двадцати человек в мире действительно знают, как использовать .gc () - вчера вечером я несколько часов работал над центральным / критическим структура данных, использующая данные, сгенерированные SecureRandom, где-то чуть дальше 40 000 объектов, виртуальная машина замедлится, как если бы в ней не было указателей. Ясно, что он подавлял 16-битные таблицы указателей и демонстрировал классическое поведение «сбойного механизма».
Я пробовал -Xms и так далее, продолжал немного вертеться, пока не достигнет 57, ххх что-то. Затем он будет запускать gc, скажем, с 57 127 до 57 128 после gc () - примерно с тем же темпом вздутия кода в лагере Easy Money.
Ваш дизайн нуждается в фундаментальной переработке, возможно, в подходе с раздвижными окнами.
источник
Вы можете запустить GC из командной строки. Это полезно для пакета / crontab:
Видеть :
источник
Спецификация JVM не говорит ничего конкретного о сборке мусора. Благодаря этому поставщики могут свободно внедрять GC по-своему.
Таким образом, эта неопределенность вызывает неопределенность в поведении сборки мусора. Вы должны проверить детали JVM, чтобы узнать о подходах / алгоритмах сбора мусора. Также есть опции для настройки поведения.
источник
Если вам нужно форсировать сборку мусора, возможно, вам следует подумать о том, как вы управляете ресурсами. Вы создаете большие объекты, которые сохраняются в памяти? Вы создаете большие объекты (например, графические классы), которые имеют
Disposable
интерфейс и не вызывают,dispose()
когда закончите с ним? Вы объявляете что-то на уровне класса, что вам нужно только в одном методе?источник
Было бы лучше, если бы вы описали причину, по которой вам нужна сборка мусора. Если вы используете SWT, вы можете использовать такие ресурсы, как
Image
иFont
для освобождения памяти. Например:Есть также инструменты для определения нераспределенных ресурсов.
источник
Если у вас заканчивается память и
OutOfMemoryException
вы можете получить ее , попробуйте увеличить объем кучи, доступной для Java, запустив программуjava -Xms128m -Xmx512m
вместо простоjava
. Это даст вам начальный размер кучи 128 МБ и максимум 512 МБ, что намного больше, чем стандартные 32 МБ / 128 МБ.источник
java -Xms512M -Xmx1024M
Другой вариант - не создавать новые объекты.
Объединение объектов не требуется, чтобы уменьшить необходимость GC в Java.
Пул объектов обычно не будет быстрее создания объектов (особенно для легких объектов), но он быстрее, чем сборщик мусора. Если вы создали 10000 объектов, и каждый объект был 16 байтов. Это 160 000 байтов, которые GC должен восстановить. С другой стороны, если вам не нужны все 10 000 одновременно, вы можете создать пул для переработки / повторного использования объектов, что устраняет необходимость в создании новых объектов и устраняет необходимость в GC старых объектов.
Как то так (не проверено). И если вы хотите, чтобы он был потокобезопасным, вы можете поменять LinkedList на ConcurrentLinkedQueue.
источник
В OracleJDK 10 с G1 GC один вызов
System.gc()
заставит GC очистить старую коллекцию. Я не уверен, что GC запускается немедленно. Однако GC не будет очищать коллекцию Young, даже если онаSystem.gc()
вызывается многократно. Чтобы заставить GC очистить коллекцию Young, вы должны распределить в цикле (например,new byte[1024]
без вызова)System.gc()
. ПризывSystem.gc()
по какой-то причине не позволяет GC очистить коллекцию Young.источник
Это правильно, только жест. У вас есть почти стандартные ответы, которые уже даны несколькими авторами. Давайте возьмем это по одному:
Правильно, фактического jvm нет - такова только спецификация, связка компьютерных наук, описывающая желаемое поведение ... Недавно я начал копать инициализацию объектов Java из нативного кода. Чтобы получить то, что вы хотите, единственный способ сделать то, что называется агрессивным обнулением. Ошибки, если они сделаны неправильно, настолько плохи, что мы должны ограничиться первоначальным объемом вопроса:
Большинство постеров здесь предполагают, что вы говорите, что работаете с интерфейсом, если это так, мы должны были бы увидеть, передается ли вам весь объект или один элемент за раз.
Если вам больше не нужен объект, вы можете присвоить ему значение null, но если вы ошиблись, возникнет исключение нулевого указателя. Бьюсь об заклад, вы можете добиться лучшей работы, если вы используете NIO
Каждый раз, когда вы, я или кто-либо еще получаете: « Пожалуйста, мне это ужасно нужно». Это почти универсальный предшественник почти полного уничтожения того, над чем вы пытаетесь работать… напишите нам небольшой пример кода, очищающий от него любое Фактический код используется и покажите нам свой вопрос.
Не расстраивайся. Часто это решает то, что ваш dba использует купленный где-то пакет, и оригинальный дизайн не настроен для массивных структур данных.
Это очень распространено.
источник
FYI
Вызов метода System.runFinalizersOnExit (true) гарантирует, что методы финализатора будут вызваны до завершения работы Java. Однако этот метод по своей сути небезопасен и является устаревшим. Альтернативой является добавление «ловушек отключения» с помощью метода Runtime.addShutdownHook.
Масаррат Сиддики
источник
Есть некоторый косвенный способ заставить сборщик мусора. Вам просто нужно заполнить кучу временными объектами до момента запуска сборщика мусора. Я сделал класс, который заставляет сборщик мусора таким образом:
Использование:
Я не знаю, насколько этот метод полезен, потому что он постоянно заполняет кучу, но если у вас есть критически важное приложение, которое ДОЛЖНО форсировать GC - когда это может быть Java-способ форсировать GC.
источник
Я хотел бы добавить кое-что здесь. Обратите внимание, что Java работает на виртуальной машине, а не на реальной машине. Виртуальная машина имеет свой собственный способ связи с машиной. Это может меняться от системы к системе. Теперь, когда мы вызываем GC, мы просим виртуальную машину Java вызвать сборщик мусора.
Поскольку сборщик мусора работает с виртуальной машиной, мы не можем заставить ее выполнить очистку тут же. Скорее, мы ставим наш запрос в очередь на сборщик мусора. Это зависит от виртуальной машины, после определенного времени (это может измениться от системы к системе, как правило, когда пороговая память, выделенная для JVM заполнена), фактическая машина освободит пространство. : D
источник
Следующий код взят из метода assertGC (...). Он пытается заставить недетерминированный сборщик мусора собирать.
Источник (я добавил некоторые комментарии для ясности): Пример NbTestCase
источник
Вы можете попробовать использовать
Runtime.getRuntime().gc()
или использовать служебный метод.System.gc()
Примечание. Эти методы не гарантируют GC. И их область должна быть ограничена JVM, а не программно обрабатывать это в вашем приложении.источник
Если вы используете JUnit и Spring, попробуйте добавить это в каждый тестовый класс:
источник