Java -> System.gc (); Этот вызов открывает новую тему или нет? - PullRequest
5 голосов
/ 19 апреля 2010

Например у меня такой код

... получить немного памяти и потерять все указатели на эту память, чтобы System.gc (); могу собрать.

вызов System.gc ();

выполнять другие задачи;


Здесь написано "делать другие задачи"; и "System.gc ();" работает в параллельном режиме или выполняет «другие задачи»; ожидает "System.gc ();" быть исполненным

Спасибо

Ответы [ 9 ]

7 голосов
/ 19 апреля 2010

Вы, вероятно, не должны использовать System.gc (). Распространенное заблуждение пользователей C / C ++, приходящих на java, заключается в том, что они думают, что должны сообщить виртуальной машине, когда она может выполнять сборку мусора. Реальность такова, что сборщик мусора высоко оптимизирован и выполняет эту задачу сам, когда считает, что это лучше всего сделать. Вызов System.gc () обычно не рекомендуется.

Если вы вызовете System.gc (), система «порекомендует» выполнить сборку мусора. На самом деле он может не выполнять коллекцию, хотя обычно это происходит. Если он выполняется в другом потоке, зависит от фактического алгоритма сбора. По умолчанию все будет заблокировано во время работы. Так что он может работать в отдельных потоках, но при этом заблокирует ваше текущее выполнение.

6 голосов
/ 19 апреля 2010

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

На практике мое наблюдение за JVM, которое я наблюдал, состояло в том, что оно сразу запускается в отдельном потоке. Однако в некоторых случаях множественные вызовы порождают несколько потоков, иногда он ставит запросы в очередь в одном потоке. Запущенная сборка мусора всегда была «остановкой мира» (то есть была очень полной и замедляла или приостанавливала работу приложения).

Однако, учитывая ваш комментарий к @Chris Dail, ваша основная проблема не в поведении вызова System.gc (). Вызов System.gc () может иметь несколько применений. Можно использовать чистую память, чтобы вы могли понять, насколько велика площадь приложения в настоящее время. Он также может быть использован в качестве стратегии для обеспечения того, чтобы сборщик мусора с остановкой происходил раньше, так что он «останавливает мир» на более короткий промежуток времени, поскольку для очистки требуется меньше памяти. (Должен отметить, что по мере того, как JVM становятся все более и более изощренными, подобные вещи становятся все менее и менее необходимыми и фактически становятся контрпродуктивными).

Однако то, что он не делает, в любом случае решает ошибку OutOfMemoryError. JVM не выдаст вам ошибку OutOfMemoryError, пока не соберет мусор в меру своих возможностей. Вызов System.gc не меняет этого. Если у вас есть OutOfMemoryError, это, вероятно, связано с тем, что вы держите ссылку на объекты способами, которые вам на самом деле не нужны, но препятствуют восстановлению памяти этих объектов.

4 голосов
/ 19 апреля 2010

Обычно это синхронно, но не гарантируется.

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

Если вам нужна дополнительная информация, вы можете запустить программу с флагом -verbosegc.

В любом случае сборщик мусора - это то, что он генерирует автоматически JVM без каких-либо заданных вызовов. Вызов System.gc() - это просто подсказка, которую вы даете, чтобы сообщить, что она может начать сбор.

1 голос
/ 19 апреля 2010

Как указал Эрик Эйкеленбоом , вызов этого метода не означает, что сборщик мусора будет выполнен немедленно. На самом деле вы не знаете, будет ли он вообще вызываться ...

В вашем случае (судя по комментарию к ответу Amarghosh ) вам нужно освободить часть памяти, прежде чем делать что-то, требующее большого количества оперативной памяти, я прав? В этом случае вам не нужно беспокоиться. Если памяти достаточно для сбора мусора, это будет выполнено автоматически при попытке выделить ее.

1 голос
/ 19 апреля 2010

Как выполняется сборка мусора, зависит от реализации JVM.Обычные реализации могут останавливать все потоки, собирать память глобально, останавливать только один поток, чтобы, например, собирать память локально для этого потока.Узнайте больше о сборке мусора от Sun и в этой более старой, но хорошей статье .

0 голосов
/ 19 апреля 2010

Согласно спецификации Java, поток, который вызывает System.gc(), останавливается до тех пор, пока GC не выполнит свое действие. Обратите внимание, что это всего лишь подсказка, JVM может игнорировать ее, и JVM от Sun фактически имеет переключатель командной строки (-XX:-DisableExplicitGC) для этого. С этим переключателем System.gc() ничего не делает и немедленно возвращается.

В любом случае, ничто в спецификации не препятствует запуску других потоков. Это зависит от алгоритма GC; JVM от Sun включает несколько, некоторые из которых способны работать одновременно с аппликативными потоками для большей части их работы.

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

0 голосов
/ 19 апреля 2010

Javadoc сообщает http://java.sun.com/j2se/1.4.2/docs/api/java/lang/System.html#gc(): « Когда управление возвращается из вызова метода, виртуальная машина Java сделала все возможное, чтобы освободить пространство от всех отброшенных объектов. Так что я бы сказал, что «делай какие-то другие задачи»; ожидает "System.gc ();" быть исполненным!

Параллелизм не используется - и это не хорошо для приложений Java. На самом деле, никогда не стоит вызывать / форсировать сборщик мусора. Это должно быть зарезервировано для крайних случаев без других решений ...

Bye, Alban.

0 голосов
/ 19 апреля 2010

Нет способа узнать. Вызов System.gc() не означает, что сборка мусора выполняется в ту же секунду, это просто запланировано. Это зависит от JVM, чтобы выполнить сборку мусора в подходящее время.

0 голосов
/ 19 апреля 2010

«Выполнить какую-либо другую задачу» ожидает выполнения и возврата System.gc().

...