Ваша предыдущая сессия не прервана или завершена с ошибкой astra linux
Обновлено: 21.11.2024
От oub at mat.ucm.es Чт, 1 января 19:19:58 2015 От: oub at mat.ucm.es (Уве Брауэр) Дата: Чт, 01 января 2015 г., 19:19:58 +0100 Тема: gpg vs smime, snowden и т. д. Message-ID: Здравствуйте, извините, если это немного не по теме, но я не знаю, где спросить. Я использую и gpg, и smime (позднее либо с gpgsm, либо с Thunderbird). Недавно немецкий журнал новостей «Der Spiegel»? [1] опубликовал больше «файлов Сноудена», которые показывают, что gpg безопасен для NSA[2]. Кто-нибудь знает, имеет ли smime такой же уровень безопасности? Есть как минимум два возможных слабых места. - генерация и подпись сертификата, в идеале генерация пары ключей должна производиться криптомодулем браузера, но это может быть взломано. - длина ключа для симметричного шифрования. Может быть, есть и другие. Любые комментарии? Спасибо, Уве Брауэр. Сноски: [1] и, полагаю, также The Guardian и New York Times. [2] хотя в документах нет информации о длине ключа и версии gpg --------------- следующая часть -------------- A нетекстовое вложение удалено. Имя: smime.p7s Тип: application/pkcs7-signature Размер: 6007 байт Описание: недоступно URL:
От 2014-667rhzu3dc-lists-groups atrisup.net, пятница, 2 января 16:29:28 2015 От: 2014-667rhzu3dc-lists-groups atrisup.net (MFPA) Дата: пятница, 2 января 2015 г., 15:29 :28 +0000 Тема: Создать открытый ключ так, чтобы закрытый ключ совпадал с заданной строкой (мой пароль)? In-Reply-To: Ссылки: Message-ID: ----- BEGIN PGP SIGNED MESSAGE ----- Хэш: SHA512 Привет, в пятницу, 2 января 2015 г., в 14:13:53, Бен Стауд написал: > Но, как я уже упоминал, я не хочу > зависеть от секретного ключа, хранящегося где-то, но я хотел бы > использовать свой пароль в качестве закрытого ключа. Мне понадобится> ключевая пара, где открытый ключ — это какой-то > мне все равно-ascii-массовый, но закрытый ключ — это > точно мой пароль. Цитата из [0]: - Когда вы генерируете пару ключей, вы делаете это с помощью: 1. детерминированной процедуры; 2. источник случайных битов. Например, с помощью RSA вы генерируете p и q, создавая случайные нечетные числа нужного размера и повторяя цикл до тех пор, пока не будет найдено простое число. Для данного случайного источника весь процесс является детерминированным: при одинаковых случайных битах будут найдены одни и те же простые числа p и q. Следовательно, вы можете разработать PRNG с секретным ключом K и использовать его в качестве случайного источника для процесса генерации ключа. Всякий раз, когда вам нужен закрытый ключ, вы снова запускаете процесс генерации ключа, используя K в качестве входных данных. И вуаль?! Ваш закрытый ключ, который вам нужно сохранить, теперь K. [0] - -- С наилучшими пожеланиями, MFPA mailto:2014-667rhzu3dc-lists-groups atrisup.net Путаница всегда самый честный ответ -----НАЧАЛО PGP ПОДПИСИ ----- iQF8BAEBCgBmBQJUprloXxSAAAAAAC4AKGlzc3Vlci1mcHJAbm90YXRpb25zLm9w ZW5wZ3AuZmlmdGhob3JzZW1hbi5uZXRCM0FFN0VDQTlBOEM4QjMwMjZBNUEwRjU2 QjdDNzRDRUIzMUYyNUYwAAoJEGt8dM6zHyXwX0gH / Aiu7hzfr5cNxI4EYSYenIXw OJ / VUyVlkbrdveiPNL3A2xjCWDHK8f915kYp7MgAqSWP6utAt8iepp4BTXg4ZQR3 SR2lSMR1sIvCSJThNHiXvT4PtvqaCZBwGyXB + QOtHxCkPos2Q + pl9zrJ42ZyQjqv EgCeygLelOoaa4E3k01uiYVAP2FjZWHu8zIhJXFBK3fLdYQjcSfZaW1udK26kaJW IcMXhUR6QX2DtdcM98o8hIKlCgWeu3rawoPaS6pzinzpgb38Z + JNx6DZY9qUQopr ouMOmV6u7d / lXYZn93zCC5731HO1On8mZaQJGR3TZZZyY + G0QUVdt5R25LmOAkqI vgQBFgoAZgUCVKa5bl8UgAAAAAAuAChpc3N1ZXItZnByQG5vdGF0aW9ucy5vcGVu cGdwLmZpZnRoaG9yc2VtYW4ubmV0MzNBQ0VENEVFOTEzNEVFQkRFNkE4NTA2MTcx MkJDNDYxQUY3NzhFNAAKCRAXErxGGvd45BrgAQD2qgZm3vkJigsuMq / MqKcVI1MZ C6Ag2W2w41MsDxgH7QEApa49lZOtUvnNrRYGKG561urKOzwcY3E1ueRTzf + rMwk = = ZJAL ----- Е.Н. ПОДПИСЬ D PGP----- От sben1783 на yahoo.de Пт, 2 января 17:04:33 2015 От: sben1783 на yahoo.de (Бен Стауд) Дата: Пт, 02 января 2015 17:04:33 +0100 Тема: Создать открытый ключ, чтобы закрытый ключ равнялся заданной строке (мой пароль)? In-Reply-To: Ссылки: Message-ID: [. ] > Еще одна мысль: вы можете сгенерировать пару ключей с размером ключа, достаточно маленьким, чтобы > помнить также пароль, но тогда я думаю, что размер ключа настолько мал, что больше не будет > безопасным. Будет ли размер ключа, соответствующий размеру моего пароля (скажем, 15 символов), менее безопасным, чем симметричное шифрование с этим паролем? Другой мыслью было бы просто вставить закрытый ключ (зашифрованный моим паролем) в файлы gpg? Конечно, тогда мой закрытый ключ будет своего рода «открытым», но все же он так же безопасен, как использование симметричного шифрования с этим паролем в первую очередь (но позволяет мне использовать настоящий открытый ключ в моем сценарии)? Gpg случайно не предлагает какую-то подобную функцию. Бен От Питера с digitalbrains.com Пт, 2 января 17:11:19 2015 От: Питера с digitalbrains.com (Питер Леббинг) Дата: Пт, 02 января 2015 17:11:19 +0100 Тема: Создать открытый ключ, чтобы получить закрытый ключ равно заданной строке (мой пароль)? In-Reply-To: Ссылки: Message-ID: 01.02.15 13:14, sben1783 написал: > Что я хотел бы сделать, так это: создать открытый ключ, чтобы соответствующий закрытый > ключ был равен моему заданному паролю .Это возможно с криптографией на основе эллиптических кривых, хотя вы должны понимать, что фраза-пароль обычно содержит намного меньше энтропии, чем закрытый ключ, основанный на случайных числах. Это означает, что можно попробовать парольные фразы для вашего открытого ключа и попробовать их в качестве секретного ключа, что невозможно с обычными секретными ключами. Однако OpenPGP и GnuPG этого не поддерживают. Примером программного обеспечения, использующего это свойство ключей ECC, является SECCURE[1]. Это не рекомендация, и я также не рекомендую против этого. Я просто не делаю заявлений о его безопасности. Кроме того, что я скажу сейчас, т.е. Единственным входом для генерации ключа в SECCURE является ваш пароль; соления нет. Один и тот же пароль ведет к одному и тому же открытому ключу. Если бы вы использовали, например, PBKDF2 для генерации открытого ключа, вы бы, по крайней мере, укрепили пароль против ряда атак, таких как радужные таблицы. Я не знаю, почему автор SECCURE не использовал это; это увеличило бы размер открытого ключа как минимум на 13 символов (что сделало бы его на 50% длиннее), но мне это кажется хорошим компромиссом. Здоровья, Питер. [1] http://point-at-infinity.org/seccure/ -- Я использую GNU Privacy Guard (GnuPG) в сочетании с Enigmail. Вы можете отправить мне зашифрованную почту, если хотите конфиденциальности. Мой ключ доступен по адресу От Питера с digitalbrains.com Пт, 2 января 17:14:22 2015 От: Питера с digitalbrains.com (Питер Леббинг) Дата: Пт, 02 января 2015 17:14:22 +0100 Тема: Создание открытого ключа так что закрытый ключ равен заданной строке (мой пароль)? In-Reply-To: Ссылки: Message-ID: 01.02.15 17:04, Ben Staude написал: > Еще одна мысль - просто вставить закрытый ключ (зашифрованный моим > паролем) в файлы gpg'd ? Конечно, тогда мой закрытый ключ был бы чем-то вроде > «открытого», но все же он так же безопасен, как использование симметричного шифрования с этим > паролем в первую очередь (но позволяет мне использовать настоящий открытый ключ в моем > сценарии)? Да, это вполне возможно. Это так же безопасно, как и использование режима gpg --symmetric с одним и тем же паролем для каждого файла, который вы шифруете. > Gpg случайно не предлагает какую-то подобную функцию? Какую функцию вы просите? Мне кажется, ему не нужна фича, не нужна явная поддержка. Вы записываете копию ключа в тот же каталог, где вы храните зашифрованные файлы. Вы пишете сценарий, который извлекает закрытый ключ оттуда в секретную связку ключей GnuPG. GnuPG никогда не нужно знать ;). ХТ, Питер. -- Я использую GNU Privacy Guard (GnuPG) в сочетании с Enigmail. Вы можете отправить мне зашифрованную почту, если хотите конфиденциальности. Мой ключ доступен по адресу От Питера с digitalbrains.com Пт, 2 января 17:37:19 2015 От: Питера с digitalbrains.com (Питер Леббинг) Дата: Пт, 02 января 2015 17:37:19 +0100 Тема: Выбор ключа В -Reply-To: Ссылки: Message-ID: 31/12/14 22:09, Sandeep Murthy написал: > Это явно ошибка, и, конечно же, есть простое решение для нее. Я при всем уважении не согласен с обоими. Редактирование отозванного ключа может быть бесполезным, но редактирование ключа с истекшим сроком действия вполне допустимо, т. е. для продления срока его действия. Поведение сопоставления также ясно и известно: без конкретики, один из совпадающих ключей. Если быть точным и применимым к 1.4 и 2.0: первый в связке ключей. При всем уважении, то, что это не соответствует тому, что вы хотели бы видеть, является чем-то иным, чем «это явно ошибка». И нельзя сказать, есть ли простое решение, не зная внутренней структуры GnuPG. Я думаю, что сопоставление первого ключа, который вы найдете, не должно ничего знать, кроме идентификатора ключа и UID. Соответствие другим характеристикам означает, что вам нужно проанализировать более подробную информацию о ключе, что может быть сделано только после выбора ключа. Не ясно, что это легко исправить. Может быть, может не быть. Патчи могут приветствоваться, если это небольшой патч с четким поведением, то есть легко проверить правильность и полноту. Хотя я склоняюсь к тому, что патч не такой уж маленький и понятный. > Эта проблема характерна для программы командной строки, а не для какой-либо > программы с графическим интерфейсом, такой как Keychain (из комплекта MacGPG2), потому что там пользователь может видеть > ключи и знать, какой из них редактировать. Для командной строки это двухэтапный процесс, который требует от пользователя повторения 8 шестнадцатеричных символов, если у него нет мыши: они также могут копировать-вставлять. Конечно, это не так много работы. $ gpg2 -k lebbing pub 1024R/3E4FCA14 31-03-2006 [аннулировано: 12-11-2009] uid [аннулировано] Peter Lebbing
pub 2048R/DE500B3E 2009-11-12 [срок действия истекает: 27 октября 2015] uid [ultimate] Питер Леббинг
писал: [. ] > Какую функцию вы просите? Мне кажется, > функция не нужна, > не нужна явная поддержка. Вы записываете копию ключа в > тот же каталог >, где вы храните зашифрованные файлы. Вы пишете сценарий, который > извлекает > закрытый ключ оттуда в секретную связку ключей GnuPG. GnuPG никогда не нужно > знать ;). О, да, это действительно охватывает то, что я написал.На самом деле я хотел написать: не мог ли gpg встроить закрытый ключ в файл gpg, например, как часть заголовка? Таким образом, независимо от того, что происходит с моим файлом gpg с точки зрения перемещения или чего-то еще, закрытый ключ с ним (лично я не возражал бы против дополнительных байтов с каждым файлом). При расшифровке gpg найдет закрытый ключ в заголовке и просто запросит у меня парольную фразу, как это происходит при симметричном шифровании. Возможно, это не такой распространенный вариант использования, но я думаю, что для меня это было бы вполне разумно;) Бен От cvimail81 на gmail.com Пт, 2 января 20:34:44 2015 От: cvimail81 на gmail.com (Эгон) Дата : Пт, 02 января 2015 г. 20:34:44 +0100 Тема: Симметричное шифрование большого количества файлов (пакетный режим) Идентификатор сообщения: Привет всем! Я хочу симметрично зашифровать многие сотни файлов под Linux, файлы, хранящиеся во многих подкаталогах. Я ищу сценарий оболочки, который может сделать это за меня. Каков самый простой способ сделать это? С наилучшими пожеланиями, Эгон От Питера с digitalbrains.com Пт, 2 января 21:35:12 2015 От: Питера с digitalbrains.com (Питер Леббинг) Дата: Пт, 02 января 2015 21:35:12 +0100 Тема: Создать открытый ключ так этот закрытый ключ равен заданной строке (мой пароль)? In-Reply-To: Ссылки: Message-ID: 01.02.15 21:29, sben1783 написал: > Возможно, это не такой уж распространенный вариант использования, но я думаю, что для меня это было бы совершенно > логично ;) Нет, я не думаю, что это станет фичей :). Однако, если вашей ОС является Linux или что-то с такой же «сценарной мощью», вы можете просто создать в своем сценарии tar-файл с закрытым ключом и зашифрованным файлом, а сценарий, который распаковывает tar во временный каталог, импортирует закрытый ключ и расшифровывает файл. Все это можно сделать с помощью простого [1] скрипта bash, tar и некоторого творчества. ХТ, Питер. [1] Я думаю, что это останется относительно простым, но вам, возможно, придется немного подумать об этом. -- Я использую GNU Privacy Guard (GnuPG) в сочетании с Enigmail. Вы можете отправить мне зашифрованную почту, если хотите конфиденциальности. Мой ключ доступен по адресу От sben1783 на yahoo.de Пт, 2 января 21:36:16 2015 От: sben1783 на yahoo.de (sben1783) Дата: Пт, 02 января 2015 г., 21:36:16 +0100 Тема: Создать открытый ключ, поэтому этот закрытый ключ равен заданной строке (мой =?UTF-8?Q?password=29=3F?= In-Reply-To: References: Message-ID: On Fri, 02 Jan 2015 18:07:40 +0100, Peter Леббинг
-------------- следующая часть --------------- Нетекстовое вложение удалено. Имя: lock-obj-pub.arm-none-linux-gnueabi.h Тип: text/x-chdr Размер: 508 байт Описание: недоступно URL:
От ryan с b19.org, понедельник, 5 января 06:33:03 2015 От: ryan с b19.org (Райан Соухилл) Дата: понедельник, 5 января 2015, 00:33:03 -0500 Тема: Симметричное шифрование многих файлов ( пакетный режим) In-Reply-To: Ссылки: Message-ID: Предполагая, что вы хотите зашифровать каждый отдельный файл в дереве каталогов, лучше всего использовать команду find. Примерно так: find /SomeDirectory -type f -exec gpg2 --batch --cipher-algo AES256 --force-mdc --симметричный --passphrase-file /FILE -o <>.gpg <> \; Приведенное выше сохранит каждый файл с тем же именем + расширением «.gpg». Конечно, параметры cipher-algo и force-mdc не требуются. Просто личная рекомендация. -------------- следующая часть -------------- Вложение HTML удалено. URL-адрес:
Последние пару месяцев мы работали над устранением узких мест в производительности для клиентов с большими задержками сетевых подключений между Traveler и внутренними почтовыми серверами.
Потребовалось некоторое время, прежде чем мы внедрили все исправления после очень подробного анализа (например, я написал менеджер расширений для отслеживания чтения объектов).
Хорошей новостью является то, что исправления включены в текущую версию, а большинство настроек теперь даже включены по умолчанию в последних версиях.
[Примечание о задержке, принятой Traveler]
IBM/HCL рекомендует, чтобы соединение между вашими почтовыми серверами и серверами Traveler имело задержку менее 50 мс!
Но у вас не всегда есть выбор. С другой стороны, сегодня я видел корпоративные сетевые соединения с задержкой около 5/6 мс!
Даже подключение к Интернету между двумя разными провайдерами, которые я использую, составляет около 6 мс!
См. техническое примечание с рекомендациями и инструкциями по устранению неполадок:
Мое первое наблюдение заключалось в том, что вложения к сообщениям в форматированном тексте отправляются по сети несколько раз во время синхронизации, что привело к первому исправлению, уже реализованному в потоке кода Traveler 9.0.1.
После того, как мы получили исправление, я понял, что сообщения MIME также были обработаны аналогичным образом — просто их было сложнее отследить.
Особенно в сетях WAN многократная передача вложений приводит к дополнительной нагрузке на сеть и в сочетании с более высокой задержкой также замедляет синхронизацию.
Не только когда вложение синхронизировано, потому что в некоторых случаях вложения могут быть предварительно переданы в потоковом режиме.
Изменения очень низкоуровневые в том, как Traveler использует API Domino. Таким образом, накладные расходы можно было отслеживать только ниже интерфейса Traveler с Domino (вызовы C-API).
В Traveler 10.0.1/10.0.0 были внесены два множества изменений, а для одного исправления требовался измененный файл notes.ini, чтобы не выполнять предварительную потоковую передачу вложения.
В наших первых исправлениях этот параметр нужно было отключить NTS_ATTACHMENT_PRESTREAM=false, но начиная с версии 10.0.1 этот параметр отключен по умолчанию.
Предварительный поток вложений был необходим для устройств Blackberry, которым требуется точный размер перед синхронизацией документа. Если у вас нет устройств Blackberry, вам подойдет новое значение по умолчанию.
Двумя основными исправлениями являются следующие:
Traveler 10.0.1.1
TRAV-3279 Обработка сообщений MIME считывает вложения несколько раз
Traveler 10.0
TRAV-3004 Избегайте потоковой передачи вложений только для расчета размера.
Кроме того, в Traveler 10.0 представлены два других исправления оптимизации для медленных сетевых подключений:
TRAV-3165 Уменьшите ведение журнала Dispatch, чтобы снизить нагрузку на сеть.
Очередь главного монитора TRAV-2952 ограничена медленным откликом почтовых серверов.
Оптимизация сетевых сеансов
Есть один дополнительный параметр notes.ini, который полезен для оптимизации внутренних соединений между Traveler и почтовыми серверами Domino.
Я работал в двух крупных средах с большим количеством почтовых серверов Domino в одном пуле высокой доступности Traveler.
Обычно следует использовать отдельные пулы Traveler для серверов в разных местах, и рекомендуется размещать пул Traveler в том же центре обработки данных, что и ваши почтовые серверы. Но это возможно не во всех клиентских средах.
В сочетании с большим количеством пользователей на разных почтовых серверах и одним пулом высокой доступности Traveler мы наблюдаем множество открытых сетевых подключений на каждый почтовый сервер.
Вы можете просмотреть до 40 УСТАНОВЛЕННЫХ сетевых сессий с почтовыми серверами в течение более длительного времени.
Следующий (наконец-то официально задокументированный) параметр NTS помогает оптимизировать и правильно перезапускать эти сетевые сеансы Domino NRPC между Traveler и вашими почтовыми серверами.
Если вы столкнулись с большим количеством открытых сеансов NRPC на внутренних почтовых серверах Domino, вам следует обратить внимание на этот параметр.
Полиция разыскивает группу мужчин, обвиняемых в использовании лома в ходе «трусливого» нападения на скоростном шоссе на юге Сиднея.
Кадры видеонаблюдения из туннеля M5 в Арнклиффе показывают, как черный BMW X5 на высокой скорости таранит Holden Astra в октябре прошлого года.
Атака вынудила Astra врезаться в стены туннеля, едва не задев несколько других автомобилей.
Полиция сообщила, что один из мужчин в BMW бросил лом в Astra, когда она остановилась на светофоре на Седьмой авеню в Маскоте.
Полицейские утверждают, что мужчины внутри BMW затем преследовали Astra на высокой скорости в восточном направлении M5, где она разбилась, прежде чем покинуть место происшествия.
Главный инспектор Фил Брукс сказал, что это был серьезный случай агрессивного поведения на дороге, который мог иметь катастрофические последствия.
"Это очень оживленная часть Сиднея, и на территории аэропорта и вокруг него было бы много пробок", – сказал он.
"Это явный случай дорожного гнева.
"Четверо молодых людей в этом черном BMW X5 вели себя очень трусливо, что напугало этих трех молодых людей в Holden Astra.
"Учитывая текущее состояние дорожных сборов — 392 в прошлом году и 29 в этом году — именно такое рискованное вождение уносит жизни на наших дорогах".
Момент, когда черный BMW протаранил Holden Astra, в результате чего он врезался в стену туннеля M5. (Прилагается: Полиция Нового Южного Уэльса)
Мужчина, предположительно бросивший лом в «Астру», описывается как мужчина европеоидной расы, около 20 лет, со светлыми/каштановыми волосами, в черном джемпере и черных шортах.
"Мы, безусловно, обращаемся ко всем, у кого есть записи с видеорегистраторов этого события, происходящего в воскресенье, 15 октября, в 20:45 – – сказал старший инспектор Брукс.
"Мы также обращаемся к предприятиям, где останавливался этот черный BMW, заправочным станциям или ресторанам".
Главный инспектор Брукс призвал всех, у кого есть информация, связаться с Crime Stoppers.
Опубликовано 31 января 2018 г. 31 января 2018 г. Ср 31 января 2018 г. в 01:14 , обновлено 31 января 2018 г. 31 января 2018 г. Ср 31 января 2018 г. в 1:47
Одним из основных преимуществ Java является автоматизированное управление памятью с помощью встроенного сборщика мусора (сокращенно GC). Сборщик мусора неявно заботится о выделении и освобождении памяти и, таким образом, способен справиться с большинством проблем с утечкой памяти.
Хотя сборщик мусора эффективно обрабатывает большую часть памяти, он не гарантирует надежного решения проблемы утечки памяти. GC довольно умен, но не безупречен. Утечки памяти могут подкрасться даже в приложениях добросовестного разработчика.
Все еще могут возникать ситуации, когда приложение создает значительное количество лишних объектов, тем самым истощая важные ресурсы памяти, что иногда приводит к сбою всего приложения.
Утечки памяти — настоящая проблема Java. В этом руководстве мы увидим, каковы потенциальные причины утечек памяти, как распознать их во время выполнения и как бороться с ними в нашем приложении.
2. Что такое утечка памяти
Утечка памяти — это ситуация, когда в куче есть объекты, которые больше не используются, но сборщик мусора не может удалить их из памяти и, следовательно, их обслуживание не требуется.
Утечка памяти — это плохо, потому что она блокирует ресурсы памяти и со временем снижает производительность системы. И если не принять меры, приложение в конечном итоге исчерпает свои ресурсы и завершится с фатальной ошибкой java.lang.OutOfMemoryError.
Существует два разных типа объектов, которые находятся в памяти кучи — ссылочные и нессылочные. Объекты, на которые ссылаются, — это те, на которые все еще есть активные ссылки в приложении, тогда как объекты без ссылок не имеют активных ссылок.
Сборщик мусора периодически удаляет объекты, на которые нет ссылок, но никогда не собирает объекты, на которые все еще есть ссылки. Здесь могут возникнуть утечки памяти:
Признаки утечки памяти
- Серьезное снижение производительности при непрерывной работе приложения в течение длительного времени
- OutOfMemoryError ошибка кучи в приложении
- Спонтанные и странные сбои приложений
- В приложении время от времени заканчиваются объекты подключения
Давайте подробнее рассмотрим некоторые из этих сценариев и способы их решения.
3. Типы утечек памяти в Java
В любом приложении утечка памяти может происходить по многим причинам. В этом разделе мы обсудим наиболее распространенные из них.
3.1. Утечка памяти через статические поля
Первый сценарий, который может привести к потенциальной утечке памяти, — интенсивное использование статических переменных.
В Java срок жизни статических полей обычно соответствует сроку службы работающего приложения (если только ClassLoader не становится пригодным для сборки мусора).
Давайте создадим простую программу на Java, которая заполняет статический список:
Теперь, если мы проанализируем память кучи во время выполнения этой программы, то увидим, что между точками отладки 1 и 2, как и ожидалось, память кучи увеличилась.
Но когда мы оставляем метод populateList() в точке отладки 3, память кучи еще не подвергается сборке мусора, как видно из этого ответа VisualVM:
Однако в приведенной выше программе в строке номер 2, если мы просто удалим ключевое слово static, это приведет к резкому изменению использования памяти, как показывает этот ответ Visual VM: р>
Первая часть до точки отладки почти такая же, как и в случае static. Но на этот раз после выхода из метода populateList(), вся память списка удаляется сборщиком мусора, потому что у нас нет на него ссылок.
Следовательно, нам нужно уделять очень пристальное внимание использованию статических переменных. Если коллекции или большие объекты объявлены как статические, они остаются в памяти на протяжении всего жизненного цикла приложения, тем самым блокируя жизненно важную память, которая в противном случае могла бы использоваться в другом месте.
Как это предотвратить?
- Сведите к минимуму использование статических переменных
- При использовании синглетонов полагайтесь на реализацию, которая загружает объект лениво, а не с нетерпением.
3.2. Через незакрытые ресурсы
Всякий раз, когда мы устанавливаем новое соединение или открываем поток, JVM выделяет память для этих ресурсов. Несколько примеров включают подключения к базе данных, входные потоки и объекты сеанса.
Если вы забудете закрыть эти ресурсы, это может привести к блокировке памяти, что сделает их недоступными для сборщика мусора. Это может произойти даже в случае исключения, которое не позволяет выполнению программы достичь оператора, обрабатывающего код для закрытия этих ресурсов.
В любом случае открытые соединения, оставшиеся от ресурсов, потребляют память, и, если мы не обработаем их, они могут снизить производительность и даже привести к OutOfMemoryError.
Как это предотвратить?
- Всегда используйте блок finally для закрытия ресурсов
- Код (даже в блоке finally), который закрывает ресурсы, сам по себе не должен иметь никаких исключений
- При использовании Java 7+ мы можем использовать блок try-with-resources
3.3. Неправильная реализация equals() и hashCode()
Очень распространенной ошибкой при определении новых классов является неправильное написание переопределенных методов для методов equals() и hashCode().
HashSet и HashMap используют эти методы во многих операциях, и если их неправильно переопределить, они могут стать источником потенциальных проблем с утечкой памяти. р>
Возьмем пример тривиального класса Person и используем его в качестве ключа в HashMap:
Теперь мы вставим повторяющиеся объекты Person в Map, использующую этот ключ.
Помните, что Карта не может содержать повторяющиеся ключи:
Здесь мы используем Person в качестве ключа. Поскольку Map не допускает дублирования ключей, многочисленные повторяющиеся объекты Person, которые мы вставили в качестве ключа, не должны увеличивать объем памяти.
Но поскольку мы не определили правильный метод equals(), повторяющиеся объекты накапливаются и увеличивают объем памяти, поэтому мы видим более одного объекта в памяти. Память кучи в VisualVM для этого выглядит так:
Однако, если бы мы правильно переопределили методы equals() и hashCode(), тогда был бы только один объект Person в эту карту
Давайте посмотрим на правильную реализацию функций equals() и hashCode() для нашего класса Person:
И в этом случае верны следующие утверждения:
После правильного переопределения equals() и hashCode() куча памяти для той же программы выглядит следующим образом:
Другим примером является использование инструмента ORM, такого как Hibernate, который использует методы equals() и hashCode() для анализа объектов и сохранения их в кэше.< /p>
Вероятность утечки памяти довольно высока, если эти методы не переопределены, потому что тогда Hibernate не сможет сравнивать объекты и заполнит свой кэш повторяющимися объектами.
Как это предотвратить?
- Как правило, при определении новых объектов всегда переопределяйте методы equals() и hashCode()
- Недостаточно просто переопределить, эти методы также должны быть переопределены оптимальным образом.
3.4. Внутренние классы, которые ссылаются на внешние классы
Это происходит в случае нестатических внутренних классов (анонимных классов). Для инициализации этим внутренним классам всегда требуется экземпляр окружающего класса.
Каждый нестатический внутренний класс по умолчанию имеет неявную ссылку на содержащий его класс. Если мы используем этот объект внутреннего класса в нашем приложении, то даже после того, как наш объект содержащего класса выйдет за пределы области видимости, он не будет удален сборщиком мусора.
Рассмотрите класс, который содержит ссылки на множество громоздких объектов и имеет нестатический внутренний класс. Теперь, когда мы создаем объект только внутреннего класса, модель памяти выглядит так:
Однако, если мы просто объявим внутренний класс статическим, то та же самая модель памяти будет выглядеть так:
Это происходит потому, что объект внутреннего класса неявно содержит ссылку на объект внешнего класса, что делает его недопустимым кандидатом на сборку мусора. То же самое происходит и с анонимными классами.
Как это предотвратить?
- Если внутреннему классу не нужен доступ к членам содержащего его класса, рассмотрите возможность превращения его в статический класс
3.5. С помощью методов finalize()
Использование финализаторов — еще один источник потенциальных проблем с утечкой памяти. Всякий раз, когда метод класса finalize() переопределяется, объекты этого класса не удаляются мгновенно сборщиком мусора. Вместо этого сборщик мусора помещает их в очередь для финализации, которая происходит позднее.
Кроме того, если код, написанный в методе finalize(), не оптимален и если очередь финализатора не успевает за сборщиком мусора Java, то рано или поздно нашему приложению суждено встретить OutOfMemoryError.
Чтобы продемонстрировать это, давайте представим, что у нас есть класс, для которого мы переопределили метод finalize() и что для выполнения этого метода требуется немного времени. Когда большое количество объектов этого класса попадает в сборщик мусора, то в VisualVM это выглядит так:
Однако, если мы просто удалим переопределенный метод finalize(), та же программа выдаст следующий ответ:
Как это предотвратить?
Подробнее о методе finalize() читайте в разделе 3 (Как избежать финализаторов) нашего руководства по методу finalize в Java.
3.6. Интернированные строки
Пул Java String претерпел серьезные изменения в Java 7, когда он был перенесен из PermGen в HeapSpace. Но для приложений, работающих на версии 6 и ниже, следует быть более внимательными при работе с большими строками.
Если мы прочитаем огромный массивный объект String и вызовем intern() для этого объекта, то он попадет в пул строк, который находится в PermGen (постоянный memory) и будет оставаться там до тех пор, пока работает наше приложение. Это блокирует память и создает серьезную утечку памяти в нашем приложении.
PermGen для этого случая в JVM 1.6 выглядит в VisualVM следующим образом:
В отличие от этого, если в методе мы просто читаем строку из файла и не интернируем ее, то PermGen выглядит так:
Как это предотвратить?
- Самый простой способ решить эту проблему — выполнить обновление до последней версии Java, поскольку пул строк перемещается в HeapSpace, начиная с версии Java 7 и выше.
- При работе с большими строками увеличьте размер пространства PermGen, чтобы избежать возможных OutOfMemoryErrors:
3.7. Использование ThreadLocal
ThreadLocal (подробно обсуждается в руководстве Введение в ThreadLocal в Java) — это конструкция, которая дает нам возможность изолировать состояние для определенного потока и, таким образом, позволяет нам достичь безопасности потоков.
При использовании этой конструкции каждый поток будет содержать неявную ссылку на свою копию переменной ThreadLocal и будет поддерживать свою собственную копию вместо совместного использования ресурса несколькими потоками до тех пор, пока поток жив.
Несмотря на свои преимущества, использование переменных ThreadLocal вызывает споры, поскольку они печально известны тем, что приводят к утечкам памяти при неправильном использовании. Джошуа Блох однажды прокомментировал локальное использование темы:
«Небрежное использование пулов потоков в сочетании с небрежным использованием локальных переменных потоков может привести к непреднамеренному удержанию объектов, как отмечалось во многих местах. Но возлагать вину на местных жителей треда необоснованно».
Утечки памяти с помощью ThreadLocals
Предполагается, чтоThreadLocals будут удалены сборщиком мусора, как только удерживающий поток перестанет быть активным. Но проблема возникает, когда ThreadLocals используются вместе с современными серверами приложений.
Современные серверы приложений используют пул потоков для обработки запросов вместо создания новых (например, Executor в случае Apache Tomcat). Более того, они также используют отдельный загрузчик классов.
Поскольку пулы потоков на серверах приложений основаны на концепции повторного использования потоков, они никогда не удаляются сборщиком мусора — вместо этого они повторно используются для обслуживания другого запроса.
Теперь, если какой-либо класс создает переменную ThreadLocal, но не удаляет ее явным образом, копия этого объекта останется в рабочем потоке Thread даже после приложение останавливается, что предотвращает сборку мусора для объекта.
Как это предотвратить?
- Рекомендуется очищать ThreadLocals, когда они больше не используются — ThreadLocals предоставляет метод remove(), который удаляет значение текущего потока для этой переменной
- Не используйте ThreadLocal.set(null) для очистки значения — это фактически не очищает значение, а вместо этого ищет Map, связанную с текущим поток и установите пару ключ-значение как текущий поток и null соответственно
- Еще лучше рассматривать ThreadLocal как ресурс, который необходимо закрыть в блоке finally, чтобы убедиться, что он всегда закрыт, даже в случае исключение:
4. Другие стратегии борьбы с утечками памяти
Несмотря на то, что универсального решения для устранения утечек памяти не существует, есть несколько способов минимизировать эти утечки.
4.1. Включить профилирование
Профилировщики Java – это инструменты, которые отслеживают и диагностируют утечки памяти в приложении. Они анализируют, что происходит внутри нашего приложения — например, как выделяется память.
Используя профилировщики, мы можем сравнить различные подходы и найти области, в которых мы можем оптимально использовать наши ресурсы.
В разделе 3 этого руководства мы использовали Java VisualVM. Ознакомьтесь с нашим руководством по профилировщикам Java, чтобы узнать о различных типах профилировщиков, таких как Mission Control, JProfiler, YourKit, Java VisualVM и профилировщик Netbeans.
4.2. Подробная сборка мусора
Включив подробный сбор мусора, мы отслеживаем подробную трассировку сборщика мусора. Чтобы включить это, нам нужно добавить следующее в нашу конфигурацию JVM:
Добавив этот параметр, мы сможем увидеть подробности того, что происходит внутри GC:
4.3. Используйте эталонные объекты, чтобы избежать утечек памяти
Мы также можем использовать ссылочные объекты в Java, встроенные в пакет java.lang.ref, для устранения утечек памяти. Используя пакет java.lang.ref, вместо прямых ссылок на объекты мы используем специальные ссылки на объекты, которые позволяют легко собирать мусор.
Очереди ссылок предназначены для информирования нас о действиях, выполняемых сборщиком мусора. Для получения дополнительной информации прочитайте руководство Soft References in Java Baeldung, в частности раздел 4.
4.4. Предупреждения Eclipse об утечке памяти
Для проектов на JDK 1.5 и более поздних версиях Eclipse показывает предупреждения и ошибки при обнаружении очевидных случаев утечки памяти. Поэтому при разработке в Eclipse мы можем регулярно заходить на вкладку «Проблемы» и быть более бдительными в отношении предупреждений об утечке памяти (если они есть):
4.5. Сравнительный анализ
Мы можем измерить и проанализировать производительность кода Java, выполнив тесты производительности. Таким образом, мы можем сравнить производительность альтернативных подходов к выполнению одной и той же задачи. Это может помочь нам выбрать лучший подход и сэкономить память.
Дополнительную информацию о сравнительном тестировании см. в нашем учебном пособии по микротестированию с помощью Java.
4.6. Проверка кода
Наконец, у нас всегда есть классический олдскульный способ простого просмотра кода.
В некоторых случаях даже этот тривиальный метод может помочь устранить некоторые распространенные проблемы с утечкой памяти.
5. Заключение
С точки зрения непрофессионала, утечку памяти можно рассматривать как болезнь, которая снижает производительность нашего приложения, блокируя жизненно важные ресурсы памяти. И, как и все другие болезни, если ее не вылечить, со временем это может привести к фатальным сбоям приложения.
Утечки памяти сложно решить, и для их обнаружения требуется сложное мастерство и владение языком Java. При устранении утечек памяти не существует универсального решения, поскольку утечки могут возникать в результате самых разных событий.
Однако, если мы прибегнем к передовым методам и будем регулярно выполнять тщательную проверку кода и профилирование, то сможем свести к минимуму риск утечек памяти в нашем приложении.
Как всегда, фрагменты кода, использованные для создания ответов VisualVM, описанных в этом руководстве, доступны на GitHub.
Читайте также: