Как зайти в Даркнет?!
25th January, 01:11
6
0
Как в tkinter из поля ввода Entry получить значение в одну переменную и обновить строку кнопкой, затем получить ещё одно введённое значение и затем сложить их. Ниже пример кода
21st July, 19:00
894
0
Программа, которая создает фейковые сервера в поиске игровых серверов CS 1.6 Steam
21st March, 17:43
948
0
Очень долго работает Update запрос Oracle
27th January, 09:58
914
0
не могу запустить сервер на tomcat HTTP Status 404 – Not Found
21st January, 18:02
905
0
Где можно найти фрилансера для выполнения поступающих задач, на постоянной основе?
2nd December, 09:48
938
0
Разработка мобильной кроссплатформенной военной игры
16th July, 17:57
1724
0
период по дням
25th October, 10:44
3955
0
Пишу скрипты для BAS только на запросах
16th September, 02:42
3720
0
Некорректный скрипт для закрытия блока
14th April, 18:33
4613
0
прокидывать exception в блоках try-catch JAVA
11th March, 21:11
4381
0
Помогите пожалуйста решить задачи
24th November, 23:53
6086
0
Не понимаю почему не открывается детальное описание продукта
11th November, 11:51
4350
0
Нужно решить задачу по программированию на массивы
27th October, 18:01
4396
0
Метода Крамера С++
23rd October, 11:55
4309
0
помогите решить задачу на C++
22nd October, 17:31
4002
0
Помогите решить задачу на python с codeforces
22nd October, 11:11
4492
0
Python с нуля: полное руководство для начинающих
18th June, 13:58
2599
0
Почему вы не вызываете явно finalize() или не запускаете сборщик мусора?
Прочитав этот вопрос, я вспомнил, как меня учили Java и говорили никогда не звонить finalize() и не запускать сборщик мусора, потому что "это большой черный ящик, о котором вам никогда не нужно беспокоиться". Может ли кто-нибудь свести рассуждения об этом к нескольким предложениям? Я уверен, что мог бы прочитать технический отчет Sun по этому вопросу, но я думаю, что хороший, короткий, простой ответ удовлетворил бы мое любопытство.
Короткий ответ: Java сбор мусора-это очень тонко настроенный инструмент. System.gc() - это кувалда.
Куча Java делится на разные поколения, каждое из которых собирается с использованием своей стратегии. Если вы прикрепите профилировщик к здоровому приложению, вы увидите, что ему очень редко приходится запускать самые дорогие виды коллекций, потому что большинство объектов перехватываются более быстрым копирующим коллектором в молодом поколении.
Вызов System.gc() напрямую, хотя технически ничего не гарантирует, на практике вызовет дорогую, полную коллекцию кучи stop-the-world. Это почти всегда неправильно . Вы думаете, что экономите ресурсы, но на самом деле тратите их впустую, заставляя Java перепроверять все ваши живые объекты “just in case”.
Если у вас возникли проблемы с GC паузами в критические моменты, вам лучше настроить JVM для использования параллельного сборщика меток/развертки, который был разработан специально для минимизации времени, затраченного на паузу, чем пытаться взять кувалду к проблеме и просто разбить ее дальше.
Документ Sun, о котором вы подумали, находится здесь: Java SE 6 HotSpot™ настройка сборки мусора виртуальных машин
(Еще одна вещь, которую вы можете не знать: реализация метода finalize() на вашем объекте замедляет сборку мусора. Во-первых, потребуется два запуска GC, чтобы собрать объект: один для запуска finalize() и следующий, чтобы убедиться, что объект не был воскрешен во время завершения. Во-вторых, объекты с finalize() методами должны рассматриваться как частные случаи GC, потому что они должны собираться индивидуально, а не просто выбрасываться навалом.)
Не беспокойтесь о финализаторах.
Переключитесь на инкрементную сборку мусора.
Если вы хотите помочь сборщику мусора, null отключите ссылки на объекты, которые вам больше не нужны. Меньше пути для следования= более явный мусор.
Не забывайте, что (нестатические) внутренние экземпляры класса сохраняют ссылки на свой родительский экземпляр класса. Таким образом, внутренняя классовая нить хранит гораздо больше багажа, чем вы могли бы ожидать.
В очень близком смысле, если вы используете сериализацию и сериализовали временные объекты, вам нужно будет очистить кэш сериализации, вызвав ObjectOutputStream.reset(), или ваш процесс будет пропускать память и в конечном итоге умрет. Недостатком является то, что непереходные объекты будут повторно сериализованы. Сериализация временных результирующих объектов может быть немного более грязной, чем вы думаете!
Рассмотрите возможность использования мягких ссылок. Если вы не знаете, что такое мягкие ссылки, прочтите javadoc для java.lang.ref.SoftReference
Держитесь подальше от фантомных ссылок и слабых ссылок, если вы действительно не возбудимы.
Наконец, если вы действительно не можете терпеть GC использовать в реальном времени Java.
Нет, я не шучу.
Справочную реализацию можно скачать бесплатно, и книга Питера Дибблса из SUN действительно хороша для чтения.
Насколько далеко заходят финализаторы:
- Они практически бесполезны. Они не гарантируют, что будут вызваны своевременно или вообще (если GC никогда не запускается, то и никакие финализаторы не будут). Это означает, что вы вообще не должны полагаться на них.
- Финализаторы не гарантированно будут идемпотентными. Сборщик мусора очень заботится о том, чтобы гарантировать, что он никогда не вызовет
finalize()более одного раза для одного и того же объекта. С хорошо написанными объектами это не будет иметь значения, но с плохо написанными объектами вызов finalize несколько раз может вызвать проблемы (например, двойной выпуск собственного ресурса ... крах). - Каждый объект, имеющий метод
finalize(), должен также предоставлять методclose()(или аналогичный). Это та функция, которую вы должны вызывать. например,FileInputStream.close(). Нет никакой причины вызыватьfinalize(), когда у вас есть более подходящий метод, который должен быть вызван вами.
Реальная проблема с закрытием дескрипторов OS в finalize заключается в том, что finalize выполняются без гарантированного порядка. Но если у вас есть дескрипторы к вещам, которые блокируют (например, сокеты), потенциально ваш код может попасть в тупиковую ситуацию (совсем не тривиальную).
Так что я за явное закрытие ручек в предсказуемом порядке. В основном код для работы с ресурсами должен следовать шаблону:
SomeStream s = null;
...
try{
s = openStream();
....
s.io();
...
} finally {
if (s != null) {
s.close();
s = null;
}
}
Это становится еще более сложным, если вы пишете свои собственные классы, которые работают через JNI и открытые дескрипторы. Вам нужно убедиться, что ручки закрыты (отпущены) и что это произойдет только один раз. Часто забывают OS ручки в настольных платформах J2SE является Graphics[2D] . Даже BufferedImage.getGrpahics() потенциально может вернуть вам дескриптор, который указывает на видеодрайвер (фактически удерживающий ресурс на GPU). Если вы не освободите его самостоятельно и не оставите его сборщику мусора для выполнения этой работы - вы можете обнаружить странную OutOfMemory и подобную ситуацию, когда у вас закончились растровые изображения, отображенные видеокартой, но все еще есть много памяти. По моему опыту, это довольно часто происходит в узких петлях, работающих с графическими объектами (извлечение миниатюр, масштабирование, заточка и т. д.).
В принципе GC не заботится об ответственности программистов за правильное управление ресурсами. Он заботится только о памяти и ни о чем другом. Вызов Stream.finalize close() IMHO был бы лучше реализован, вызывая исключение new RuntimeError ("сбор мусора в потоке, который все еще открыт"). Это позволит сэкономить часы и дни отладки и очистки кода после того, как неаккуратные любители оставили концы теряют.
Счастливого кодирования.
Мир.
Если предположить, что финализаторы похожи на их тезку .NET, то вам действительно нужно вызывать их только тогда, когда у вас есть ресурсы, такие как дескрипторы файлов, которые могут протекать. В большинстве случаев ваши объекты не имеют этих ссылок, поэтому их не нужно вызывать.
Это плохо-пытаться собрать мусор, потому что это не совсем ваш мусор. Вы сказали VM выделить некоторую память при создании объектов, и сборщик мусора скрывает информацию об этих объектах. Внутренне GC выполняет оптимизацию на выделениях памяти, которые он делает. Когда вы вручную пытаетесь собрать мусор, у вас нет никаких знаний о том, что GC хочет удержать и избавиться, вы просто заставляете его руку. В результате вы путаете внутренние расчеты.
Если бы вы знали больше о том, что держит внутри себя GC, вы могли бы принимать более обоснованные решения, но тогда вы упустили преимущества GC.
Избегайте финализаторов. Нет никакой гарантии, что они будут вызваны своевременно. Это может занять довольно много времени, прежде чем система управления памятью (т. е. сборщик мусора) решит собрать объект с помощью финализатора.
Многие люди используют финализаторы для выполнения таких действий, как закрытие соединений сокетов или удаление временных файлов. Поступая таким образом, Вы делаете свое поведение приложения непредсказуемым и привязанным к тому, когда JVM собирается GC ваш объект. Это может привести к "out of memory" сценариям, но не из-за исчерпания кучи Java, а скорее из-за того, что в системе не хватает дескрипторов для конкретного ресурса.
Еще одна вещь, которую следует иметь в виду, заключается в том, что введение вызовов System.gc() или таких молотков может показать хорошие результаты в вашей среде, но они не обязательно будут транслироваться в другие системы. Не все работают одинаково JVM, есть много, SUN, IBM J9, BEA JRockit, Harmony, OpenJDK и т. д... Это JVM все соответствует JCK (те, которые были официально проверены, что есть), но имеют много свободы, когда дело доходит до быстрого создания вещей. GC - это одна из тех областей, в которые каждый вкладывает значительные средства. Использование молотка часто разрушает это усилие.