Не завидуйте мандаринкам или бессмертным, а корректируйте строчку кода долго. Оригинал: Miss Sister Taste (идентификатор публичной учетной записи WeChat: xjjdog), добро пожаловать, пожалуйста, сохраните источник для перепечатки.
Я глубоко привязался к Java с детства, и у меня десятки лет опыта работы с Java. В то время Java все еще принадлежала Sun.У меня многолетний опыт работы с Servlet и CURD.Теперь я занялся инновациями и обратился к философии жизни. Забудь, перестань дуть. Эта статья посвящена устранению неполадок в Java и является частью 1.
Просмотрите онлайн-карту мозга уценки напрямую, посетитеmind.xjjdog.cnможет быть получен
Чтобы обеспечить беглость статьи, я решил написать ее за один раз. Поскольку в смежных аспектах много обучения, нет необходимости обращаться к материалам и читать исходный код при написании. Если подумать, то на эту статью и часа не потратили, а длина уже большая.
Если он слишком длинный, он будет отрезан. Эта статья обозначена как первая часть проверки памяти, в основном говорящая о некоторых принципах. Зачем говорить о принципах? Вам все еще нужно знать устройство автомобиля, чтобы водить?
Это действительно нельзя сравнивать.
Автомобили редко ломаются, и если что-то пойдет не так, вы потратите деньги на эвакуаторы и магазины 4S. Вы также будете страховать его каждый год.
С другой стороны, в Java проблемы возникают каждые три дня и два раза, и никто не может найти того, кто их решит, даже деньги не решат проблему. Вы можете сравнить? Инвентарь к инвентарю идти, в конце концов, может полагаться только на себя.
[toc]
1. Что в памяти
Чтобы устранить проблемы с памятью, нам нужно посмотреть, что находится в памяти. Давайте сначала посмотрим на разделение памяти операционной системы, а затем посмотрим на разделение памяти JVM. Поскольку сама JVM работает в операционной системе как обычное приложение, ее поведение также ограничивается операционной системой.
2. Память операционной системы
Начнем с реализации операционной системы. Обычно мы пишем программу на языке C, и после компиляции обнаружим, что адрес памяти в ней фиксирован. На самом деле после компиляции нашего приложения эти адреса являются виртуальными адресами. Прежде чем его можно будет сопоставить с реальной физической памятью, ему необходимо пройти через уровень трансляции MMU — это аппаратное обеспечение, отвечающее за преобразование адресов.
Итак, сколько памяти доступно в нашей операционной системе? На самом деле он разделен на две части. Одна часть — это физическая память, которая относится к вставленной нами флешке; другая часть — это виртуальная память, имитируемая диском, который обычно называется разделом подкачки в Linux. Итак, доступная память = физическая память + виртуальная память. Если в вашей системе включен своп, доступная память больше, чем физическая память.
Вы можете увидеть использование памяти как через команду top, так и через команду free.
Команда top может видеть использование памяти каждым процессом.RES
Этот столбец представляет фактическое использование памяти процессом.Мы обычно отслеживаем это значение, когда строим систему мониторинга.
Давайте еще раз посмотрим на отображение команды free. Его отображение на самом деле немного сбивает с толку, и конкретные отношения можно увидеть на рисунке выше. При нормальных обстоятельствах значение, отображаемое параметром free, относительно невелико, но это не означает, что доступной памяти системы совсем немного. После запуска операционной системы Linux при работе машины оставшаяся память будет быстро заполняться буферами и кэшами, и эта память может быть освобождена, когда памяти для приложения недостаточно.Свободная память = свободная + буферы + кешированная.
Использование памяти каждой области может быть указано с помощью/proc/meminfo
для просмотра.
# cat /proc/meminfo
MemTotal: 3881692 kB
MemFree: 249248 kB
MemAvailable: 1510048 kB
Buffers: 92384 kB
Cached: 1340716 kB
40+ more ...
3. Разделение памяти JVM
Далее, давайте взглянем на разделение области памяти JVM.
В JVM самая большая область памяти — это куча, и большинство объектов, которые мы обычно создаем, хранятся здесь. Так называемая сборка мусора также в основном нацелена на эту часть.
Несколько книг по JVM описывают:В JVM, кроме счетчика программ, могут переполняться и другие области. Здесь мы по-прежнему согласны с этим выводом. Ниже приводится лишь краткое введение в эти области памяти, потому что некоторые знания бесполезны для устранения неполадок с памятью.
- куча: данные в куче JVM являются общими и занимают наибольшую область памяти
- стек виртуальных машин: стек виртуальной машины Java, основанный на потоках и используемый для обслуживания операций инструкций байт-кода.
- счетчик команд: Индикатор номера строки байт-кода, выполняемого текущим потоком.
- метапространство: здесь находится область метода, а не куча
Локальная память: другой объем памяти
По аналогии с картинкой выше мы можем определить места размещения некоторых часто используемых объектов. Не беспокойтесь об анализе выхода из выделения в стеке и не обращайте внимания на двухуровневую структуру стекового фрейма и стека операндов — эти мелкие детали слишком мало влияют на океан объектов. Интересующая нас область памяти на самом делеПамять в кучеипамять вне кучидве концепции.
4. Картинка тысячи забот, память jvm еще никогда не была такой простой!
В следующей статье подробно объясняется каждая область. Изначально хотел его замесить, но боялся, что его важность не будет выделена. Так что начните читать оригинал напрямую.
Звездная статья:«Картина тысячи печалей, память jvm еще никогда не была такой простой! 》
5. Почему возникают проблемы с памятью
Статистика показывает, что в нашей обычной работе,OOM/ML
процент проблем5%
около , среднее время обработки достигло40天
о. Видно, что исследование такого рода задач весьма затруднительно.
Но что лишает людей дара речи, так это то, что при возникновении проблем с памятью осведомленность инженеров о защите на месте часто недостаточна, особенно недостаточна. Знаю только результат переполнения памяти, но ничего не осталось. Мониторинга нет, логирования нет, и даже момент времени, когда это произошло, не ясен. Такая проблема, призрак знает причину.
6. Сборщик мусора
Существует два режима проблем с памятью: один — переполнение памяти, а другой — утечка памяти.
- переполнение памятиOutOfMemoryError, называемая OOM, куча является наиболее распространенной ситуацией, и трудно устранить неполадки памяти вне кучи.
- утечка памятиУтечка памяти, или сокращенно ML, в основном относится к тому факту, что выделенная память не была освобождена. Память растет, и есть риск OOM; коллекция, которая должна быть собрана во время GC, не может быть восстановлена или может быть переработана, но быстро заполняется, вызывая давление.
Влияние проблем с памятью также очень велико, например, в следующих трех сценариях.
- Возникает ошибка OOM, и приложение останавливается (самое серьезное)
- Частая сборка мусора, длительное время сборки мусора, использование кванта времени большого потока сборки мусора
- Служба зависает, и время ответа на запрос увеличивается
Говоря об этой проблеме с задержкой, мы должны упомянуть сборщик мусора.
Многие студенты видят картинку выше и знают, что речь идет о сборщике мусора G1, что также является моей рекомендацией. Сборщики мусора типа CMS, время сбора неконтролируемое.Если у вас есть условия, конечно, избегайте их использования.CMS тоже уберут в Java 14. Очень не хочется, чтобы у вас был какой-то опыт, который вот-вот будет устаревший. ZGC хоть и мощная, но еще слишком новая, крабов есть почти никто не решается, так что остальное - G1.
Благодаря трем простым параметрам конфигурации G1 в большинстве случаев может добиться отличной производительности, и инженеры намного счастливее. Эти три параметра следующие:
- MaxGCPauseMillisЗаданная цель, автоматическая настройка.
- G1HeapRegionSizeНебольшой размер кучи.
- InitiatingHeapOccupancyPercentПороговое значение доли памяти в куче для включения одновременной маркировки.
Если вы все еще волнуетесь и хотите понять принцип G1, то мы также можем взглянуть на него. На самом деле, у G1 все еще есть понятие молодого поколения и старого поколения, но его память не является непрерывной.
Как показано, G1 делит память на области одинакового размера, называемыенебольшая площадь кучи, это наименьшая единица сборки мусора. Предыдущие сборщики мусора рекультивировали всю генерацию, а G1 — частичную рекультивацию, тогда количество малых областей кучи можно разумно выбрать в соответствии с настроенным минимальным временем задержки, и появляется процесс рекультивацииразумныймного.
7. Важные понятия Корни GC
Как показано на диаграмме, чтобы определить, что является мусором, должен быть способ найти этот мусор. На самом деле то, что мы сказали в предыдущем предложении, неверно. В JVM способ поиска мусора прямо противоположен тому, что мы понимаем:Сначала он находит уцелевшие объекты, помечает уцелевшие объекты, а затем перерабатывает все остальные объекты.
Во время сборки мусора JVM заботится не о том, чтобы перерабатывать объекты, которые не являются мусором, но и не очищать объекты мусора.
Чтобы найти живые объекты, вам нужно проследить их от источника. В JVM общие корни GC имеют статические переменные-члены, такие как статический HashMap.
Другая часть — это содержимое стека виртуальной машины и собственного стека методов, связанного с потоком.
Мы давно об этом говорили, на самом деле у этого ретроспективного метода есть имя собственное:анализ доступности. Подобно подсчету ссылок, но из-за проблемы циклических зависимостей почти ни один сборщик не использует эту форму.
Это не значит, что пока есть связь с GC Roots (Reference Chain), объект жив, это также связано с референтным уровнем объекта.
- сильная цитата: Он принадлежит к наиболее распространенному и жесткому виду существования и будет устранен только тогда, когда разорвет свои отношения с GC Roots.
- мягкая ссылка: только когда памяти недостаточно, система восстановит программный эталонный объект.
- слабая ссылка: когда JVM выполняет сборку мусора, объекты, связанные со слабыми ссылками, будут утилизированы независимо от того, достаточно ли памяти или нет.
- фантомная ссылка: виртуальные ссылки в основном используются для отслеживания действий объектов, собираемых сборщиком мусора.
В обычных условиях объекты, которые мы используем, являются сильными ссылками. Мягкие ссылки и слабые ссылки широко используются в некоторых структурах кэширования, а важность объектов относительно невелика.
8. Подъем предметов
Большинство сборщиков мусора являются сборщиками мусора поколений, как мы можем видеть из описания G1 выше.
Как показано на рисунке, это типичная модель памяти восстановления поколения. Существует четыре способа продвижения объектов от молодого поколения к старшему поколению.
-
Регулярный буст, объект достаточно старый. Например, после 15 кругов от до до он не был переработан. Параметр управления
-XX:MaxTenuringThreshold
. Это значение по умолчанию равно 6 в CMS и 15 в G1. - Гарантия распространенияМеста для выживших мало, старость гарантия.
- большой объектВыделить непосредственно в старом поколении
- Динамическое определение возраста объекта. Например, TenuringThreshold в G1 будет меняться в зависимости от распределения объектов в куче.
Оптимизация сборщика мусора заключается в обеспечении того, чтобы в молодом поколении было выделено как можно больше объектов, чтобы уменьшить вероятность того, что объекты будут перемещены в старое поколение. Хотя эта идея была сильно ослаблена в G1.
End
Зная, что находится в памяти операционной системы и что в памяти JVM, мы можем спокойно и попустительствовать каждой проблемной ситуации, и проводить целенаправленное исследование и оптимизацию.
На этом статья резко обрывается. В следующей статье давайте рассмотрим конкретный процесс устранения неполадок с памятью Java на нескольких практических примерах.
Об авторе:Мисс сестра вкус(xjjdog), публичная учетная запись, которая не позволяет программистам идти в обход. Сосредоточьтесь на инфраструктуре и Linux. Десять лет архитектуры, десятки миллиардов ежедневного трафика, обсуждение с вами мира высокой параллелизма, дающие вам другой вкус. Мой личный WeChat xjjdog0, добро пожаловать в друзья для дальнейшего общения.