Разбор и настройка параметров JVM
Raymon 2017-06-28 JavaПолное название JVM — виртуальная машина Java. Файл .class, сгенерированный после компиляции программы Java, передается JVM для выполнения. JVM переводит содержимое файла .class на машинный язык, распознаваемый системой. Вот почему Java можно скомпилировать один раз и запускать везде.
О конфигурации JVM и настройки JVM является обязательным для Java-программистов для мастера. Отличный программист Java может установить параметры JVM в соответствии с запущенной средой, чтобы добиться оптимальной конфигурации, привести разумное и полное использование системных ресурсов и избежать некоторых вхождений В качестве OOM в производственной среде. Исключение или резьбовые тупики, Java Process CPU Расход CPU слишком высок и так далее.
Инструменты отладки JVM
jps (JVM Process Status Tool)
--- Вывести информацию о состоянии процесса Java, запущенного jvm
Формат команды:
jps [options] [hostId]
Значением hostId по умолчанию является текущий хост Команды включают:
-q 不输出类名、Jar名和传入main方法的参数
-m 输出传入main方法的参数
-l 输出main类或Jar的全限名
-v 输出传入JVM的参数
Используйте следующим образом:
[root@localhost ~]#
[root@localhost ~]# jps -m -l
28353 uyun.bat.monitor.impl.Startup
22852 uyun.bat.datastore.Startup
25799 uyun.bat.event.impl.Startup
19976 /opt/uyun/platform/jetty/start.jar
29320 uyun.bat.report.Startup
jstack
--- Вывести конкретную информацию о стеке внутрипроцессного потока Java
jstask должен быть широко используемым инструментом отладки JVM Формат команды:
jstack [option] [pid]
Командные инструкции:
-l long listings 打印线程锁信息,发生死锁时可以使用该参数调试
-m mixed mode 不仅输出java堆栈信息,还会输出C/C++堆栈信息
Пример практического применения: просмотр информации о стеке потоков процесса, занимающего больше всего ресурсов ЦП.
- ps -ef | grep Найдите соответствующий процесс или используйте команду top, чтобы просмотреть информацию об использовании системы и найти процесс, который потребляет больше всего. Здесь я использую команду top:
top - 07:38:01 up 3 days, 6:20, 5 users, load average: 15.72, 15.02, 14.14
Tasks: 148 total, 7 running, 141 sleeping, 0 stopped, 0 zombie
%Cpu(s): 71.2 us, 26.1 sy, 0.0 ni, 0.0 id, 0.0 wa, 0.0 hi, 2.7 si, 0.0 st
KiB Mem: 20397888 total, 20124388 used, 273500 free, 0 buffers
KiB Swap: 1081340 total, 1081340 used, 0 free. 2163376 cached Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
24152 es 20 0 3323892 492160 28496 S 35.7 2.4 1613:51 java
3247 mysql 20 0 1152924 297932 5836 S 9.9 1.5 418:51.47 mysqld
20009 root 20 0 3688420 1.563g 13132 S 7.9 8.0 653:51.83 java
22852 root 20 0 3450392 546480 12828 S 7.6 2.7 322:33.85 java
5779 root 20 0 3652656 1.114g 4976 S 4.3 5.7 109:57.89 java
28353 root 20 0 3624988 337680 12824 S 3.3 1.7 125:49.11 java
268 root 0 -20 0 0 0 S 2.3 0.0 43:33.35 kworker/0:1H
11539 root 20 0 369916 14108 4020 R 2.0 0.1 0:00.06 python
25799 root 20 0 3356336 475416 12832 S 1.7 2.3 64:56.00 java
1544 root 20 0 247448 27916 1144 S 1.3 0.1 56:24.67 redis-server
11540 root 20 0 131528 5048 3880 S 1.3 0.0 0:00.04 sshd
21497 root 20 0 3306144 313020 12712 S 1.0 1.5 20:59.73 java
1 root 20 0 133816 6772 2084 S 0.7 0.0 40:38.49 systemd
После того, как команда top для поиска наиболее интенсивно использующей ЦП Java является процессом, идентификатор процесса равен 24152, потребление памяти достигло 35,7%, после представления ps -ef | grep pid этот процесс является процессом ElasticSearch.
- Вторые шаги нам нужно найти самую дорогостоящую тему процессора в процессе, вы можете использовать PS -LFP PID, PS -MP PID -O TOTE, TOP -HP PID, здесь мы используем третью команду, топ-HP 24152
top - 07:44:20 up 3 days, 6:27, 5 users, load average: 19.72, 15.50, 14.42
Threads: 40 total, 1 running, 39 sleeping, 0 stopped, 0 zombie
%Cpu(s): 64.3 us, 32.0 sy, 0.0 ni, 0.0 id, 0.0 wa, 0.0 hi, 3.7 si, 0.0 st
KiB Mem: 20397888 total, 19894260 used, 503628 free, 0 buffers
KiB Swap: 1081340 total, 1081340 used, 0 free. 1994824 cached Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
24937 es 20 0 3319268 485312 21512 R 23.0 2.4 748:12.71 java
24953 es 20 0 3319268 485312 21512 S 4.3 2.4 151:27.67 java
24157 es 20 0 3319268 485312 21512 S 3.0 2.4 142:46.82 java
24459 es 20 0 3319268 485312 21512 S 0.3 2.4 1:58.92 java
24876 es 20 0 3319268 485312 21512 S 0.3 2.4 16:58.66 java
24152 es 20 0 3319268 485312 21512 S 0.0 2.4 0:00.00 java
24154 es 20 0 3319268 485312 21512 S 0.0 2.4 0:02.02 java
24155 es 20 0 3319268 485312 21512 S 0.0 2.4 0:00.00 java
24156 es 20 0 3319268 485312 21512 S 0.0 2.4 42:25.76 java
24158 es 20 0 3319268 485312 21512 S 0.0 2.4 0:31.47 java
Здесь мы видим, что pid самого дорогого потока равен 24937.
- Третий шаг — получить шестнадцатеричное значение идентификатора потока 24937.
[root@localhost ~]# printf "%x\n" 24937
6169
Затем используйте jstack для вывода информации о стеке с идентификатором потока 24937, grep в соответствии с шестнадцатеричным значением идентификатора потока.
jstack 24152 | grep 6169
Вот у меня проблема, после выполнения команды jstack система не возвращает информацию о jvm, а выдает ошибку:
Unable to open socket file: target process not responding or HotSpot VM not loaded
Сообщается о причине, по которой эта ошибка не может найти файл.Прежде всего, мы должны знать, что каталог hsperfdata_$user будет создан при запуске jvm.По умолчанию /tmp под Linux.Мы также можем настроить параметр запуска jvm -Djava.io.tmpdir Чтобы указать место хранения временного файла информации о номере процесса, после проверки подтвердите наличие сгенерированного каталога hsperfdata_es в /tmp
[root@localhost hsperfdata_es]# pwd
/tmp/hsperfdata_es
[root@localhost hsperfdata_es]# ls
24152
[root@localhost hsperfdata_es]#
Причина, по которой jstack сообщит об ошибке, что файл не может быть найден, заключается в том, что процесс ElasticSearch запущен с пользователем es, а мы вошли в систему с учетной записью root, поэтому мы не можем получить доступ к этому файлу.После переключения пользователя на es, используйте jstack для повторной печати информации о стеке потока:
[root@localhost hsperfdata_es]# su es
[es@localhost hsperfdata_es]$ jstack 24152 | grep 6169
"elasticsearch[Grenade][bulk][T#1]" #49 daemon prio=5 os_prio=0 tid=0x00007f78440b2000 nid=0x6169 runnable [0x00007f7840fa1000]
[es@localhost hsperfdata_es]$
Распечатайте информацию о потоке, показывающую, что поток находится в состоянии готовности для нормальной работы runnable.После просмотра подробной информации о стеке, это должен быть процесс, который создал индекс осколка внутри es, поэтому он требует большей производительности. Формально проверяя свой собственный процесс среды, вы можете печатать несколько раз и сравнивать условия выполнения потока несколько раз.При нормальных обстоятельствах, поскольку программа работает очень быстро, если вы обнаружите, что несколько распечаток всегда находятся в одном и том же состоянии для потока, таких как Runnable, и информация о стеке тоже застревает.В тех же местах можно рассмотреть, есть ли в соответствующем коде бесконечный цикл или медленный вызов метода.
jmap jhat
--- jmap выводит использование памяти кучи --- jhat инструмент для анализа кучи памяти Java
jmap и jhat часто используются вместе.
jmap -hap pid
Используется для просмотра использования процессов использования памяти, включая параметры конфигурации кучи и использование кучи памяти в каждом поколе, например:
whale.server01:/root# jmap -heap 17047
Attaching to process ID 17047, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.77-b03
using thread-local object allocation.
Parallel GC with 4 thread(s)
Heap Configuration:
MinHeapFreeRatio = 0
MaxHeapFreeRatio = 100
MaxHeapSize = 1073741824 (1024.0MB)
NewSize = 175112192 (167.0MB)
MaxNewSize = 357564416 (341.0MB)
OldSize = 351272960 (335.0MB)
NewRatio = 2
SurvivorRatio = 8
MetaspaceSize = 21807104 (20.796875MB)
CompressedClassSpaceSize = 1073741824 (1024.0MB)
MaxMetaspaceSize = 134217728 (128.0MB)
G1HeapRegionSize = 0 (0.0MB)
Heap Usage:
PS Young Generation
Eden Space:
capacity = 70254592 (67.0MB)
used = 22570248 (21.52466583251953MB)
free = 47684344 (45.47533416748047MB)
32.126366914208255% used
From Space:
capacity = 9961472 (9.5MB)
used = 6859688 (6.541908264160156MB)
free = 3101784 (2.9580917358398438MB)
68.86219225431743% used
To Space:
capacity = 10485760 (10.0MB)
used = 0 (0.0MB)
free = 10485760 (10.0MB)
0.0% used
PS Old Generation
capacity = 184025088 (175.5MB)
used = 99082056 (94.49201202392578MB)
free = 84943032 (81.00798797607422MB)
53.841602292835205% used
24334 interned Strings occupying 2508568 bytes.
Используйте jmap -histo[:live] pid для просмотра количества объектов в памяти кучи, гистограммы статистики размера, если вы приводите живые объекты, будут учитываться только живые объекты, следующим образом:
whale.server01:/root# jmap -histo:live 17047 | more
num #instances #bytes class name
----------------------------------------------
1: 77521 8038136 [C
2: 1056 2890752 [J
3: 6362 2595656 [B
4: 5812 1968312 [I
5: 76614 1838736 java.lang.String
6: 19709 1734392 java.lang.reflect.Method
7: 18318 1268024 [Ljava.lang.Object;
8: 10179 1136280 java.lang.Class
9: 33025 1056800 java.util.concurrent.ConcurrentHashMap$Node
10: 12388 594624 org.aspectj.weaver.reflect.ShadowMatchImpl
11: 16901 540832 java.util.HashMap$Node
12: 12304 492160 java.util.LinkedHashMap$Entry
13: 12388 396416 org.aspectj.weaver.patterns.ExposedState
14: 2633 352464 [Ljava.util.HashMap$Node;
15: 11008 352256 java.util.Hashtable$Entry
16: 436 330440 [Ljava.util.concurrent.ConcurrentHashMap$Node;
17: 13383 321192 java.util.ArrayList
18: 9319 298208 java.lang.ref.WeakReference
19: 741 278616 java.lang.Thread
20: 17352 277632 java.lang.Object
21: 5707 228280 java.lang.ref.SoftReference
22: 3612 173376 java.util.HashMap
23: 302 164288 rx.internal.util.unsafe.SpscArrayQueue
24: 5104 163328 java.util.concurrent.locks.ReentrantLock$NonfairSync
25: 2872 160832 java.util.LinkedHashMap
26: 4784 153088 java.lang.ThreadLocal$ThreadLocalMap$Entry
27: 1828 146240 java.lang.reflect.Constructor
28: 1473 139856 [Ljava.lang.ThreadLocal$ThreadLocalMap$Entry;
29: 5152 123648 java.beans.MethodRef
30: 3831 119752 [Z
31: 5550 118632 [Ljava.lang.Class;
32: 2003 112168 java.security.Provider$Service
33: 464 107616 [Ljava.util.Hashtable$Entry;
С описанием объекта класса:
B byte
C char
D double
F float
I int
J long
Z boolean
[ 数组,如[I表示int[]
[L+类名 其他对象
Другой сценарий — выгрузить использование памяти процесса с помощью jmap, а затем проанализировать его с помощью jhat. Команда выглядит следующим образом:
whale.server01:/root# jmap -dump:format=b,file=/tmp/dump.dat 17047
Dumping heap to /tmp/dump.dat ...
Heap dump file created
Используйте jhat для просмотра:
jhat -port 9998 /tmp/dump.dat
После выполнения откройте http://ip:9998 в браузере для просмотра результатов
jstat
--- вывод использования памяти jvm
Система мониторинга общего использования ресурсов jstat, использующая синтаксис:
jstat -<option> [-t] [-h<lines>] <vmid> [<interval> [<count>]]
Сцена jstat чаще используется для просмотра статистики сборки мусора в реальном времени, обычно команда выглядит следующим образом:
[root@localhost hsperfdata_root]# jstat -gc 19560 5000
То есть статус GC процесса 19560 будет отображаться каждые 5 секунд:
S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT
17472.0 17472.0 275.9 0.0 139968.0 2271.9 349568.0 21151.3 55808.0 53992.8 6400.0 6044.1 5554 30.602 4 0.809 31.411
17472.0 17472.0 275.9 0.0 139968.0 58303.5 349568.0 21151.3 55808.0 53992.8 6400.0 6044.1 5554 30.602 4 0.809 31.411
17472.0 17472.0 275.9 0.0 139968.0 102692.6 349568.0 21151.3 55808.0 53992.8 6400.0 6044.1 5554 30.602 4 0.809 31.411
17472.0 17472.0 275.9 0.0 139968.0 103396.5 349568.0 21151.3 55808.0 53992.8 6400.0 6044.1 5554 30.602 4 0.809 31.411
17472.0 17472.0 275.9 0.0 139968.0 136708.8 349568.0 21151.3 55808.0 53992.8 6400.0 6044.1 5554 30.602 4 0.809 31.411
17472.0 17472.0 0.0 273.1 139968.0 31730.4 349568.0 21151.3 55808.0 53992.8 6400.0 6044.1 5555 30.605 4 0.809 31.414
17472.0 17472.0 0.0 273.1 139968.0 64034.4 349568.0 21151.3 55808.0 53992.8 6400.0 6044.1 5555 30.605 4 0.809 31.414
Можно видеть, что при печати GC в шестой раз в приведенном выше примере выполняется YGC, и пространство памяти EU (использование eden) и S0U (использование Survivor0) очищается один раз.
Прикрепите описание каждого столбца:
S0C:第一个幸存区的大小
S1C:第二个幸存区的大小
S0U:第一个幸存区的使用大小
S1U:第二个幸存区的使用大小
EC:伊甸园区的大小
EU:伊甸园区的使用大小
OC:老年代大小
OU:老年代使用大小
MC:方法区大小
MU:方法区使用大小
CCSC:压缩类空间大小
CCSU:压缩类空间使用大小
YGC:年轻代垃圾回收次数
YGCT:年轻代垃圾回收消耗时间
FGC:老年代垃圾回收次数
FGCT:老年代垃圾回收消耗时间
GCT:垃圾回收消耗总时间
параметры JVM
Куча памяти JVM
Весь размер кучи = молодое поколение + старое поколение + пермская область памяти кучи JVM используется для объектов и массивов, созданных с помощью new, а стековая память используется для размещения переменных базового типа и ссылок на объекты, когда программа выходит за рамки, ссылки в стеке будет освобождено, а объекты в куче памяти, потерявшие адрес ссылки, станут мусором, а память будет высвобождена и освобождена сборщиком мусора в неизвестное время;
Диаграмма состава памяти кучи:
-
-Xms начальный размер кучи по умолчанию физической памяти 1/64 (менее 1 ГБ), когда размер свободной кучи меньше 40%, JVM будет увеличивать кучу до максимального предела -Xmx
-
-Xmx максимальный размер кучи Когда свободный размер кучи, равный 1/4 физической памяти по умолчанию (менее 1 ГБ), превышает 70 %, JVM уменьшит размер кучи до минимального предела -Xms.
Мы можем получить динамическую память фиксированного размера, установив одинаковый размер для "-Xms" и "-Xmx". -Xms и -Xmx на самом деле являются сокращением для -XX:InitialHeapSize и -XX:MaxHeapSize. Мы также можем использовать эти два параметра напрямую, они имеют тот же эффект.
-
-Xmn размер молодого поколения
-
-XX:NewSize Установить начальный размер молодого поколения
-
-XX: MaxNewSize молодого поколения максимального значения
-
-Xx: Permsize Настройки для начального значения продолжительности
-
-XX:MaxPermSize установить максимальное постоянное поколение
-
-Xss Размер стека каждого потока После JDK5.0 размер стека каждого потока составляет 1 М. Раньше размер стека каждого потока составлял 256 КБ. Этот параметр оказывает большое влияние и требует корректировки после строгого тестирования.
-
-XX:NewRatio Отношение молодого поколения (включая Эдем и две области Survivor) к старому поколению (исключая постоянное поколение) -XX:NewRatio=4 означает, что отношение молодого поколения к старому составляет 1:4 , а на молодое поколение приходится 1/5 всего стека, при задании Xms=Xmx и Xmn этот параметр задавать не нужно.
-
-XX:SurvivorRatio Соотношение размера области Эдема к области Выживших устанавливается равным 8, тогда соотношение двух областей Выживших к одной области Эдема составляет 2:8, и на одну область Выживших приходится 1/10 всего молодого поколения
-
-XX:+HeapDumpOnOutOfMemoryError и -XX:HeapDumpPath Когда мы не можем установить подходящий размер для -Xmx (максимальной памяти кучи), мы можем столкнуться с риском переполнения памяти (OutOfMemoryError), с которым можно столкнуться при использовании JVM. коренная причина одного из самых ужасных зверей переполнения памяти требует тщательной локализации. Вообще говоря, анализ моментального снимка памяти кучи (Heap Dump) является хорошим средством определения того, не создается ли моментальный снимок памяти при переполнении памяти, особенно для того типа JVM, который потерпел крах или ошибка возникает только после плавной работы для несколько часов или даже несколько дней.Сегодня будет сложно анализировать сбои в производственной системе.
幸运的是,我们可以通过设置 -XX:+HeapDumpOnOutOfMemoryError 让JVM在发生内存溢出时自动的生成堆内存快照。有了这个参数,当我们不得不面对内存溢出异常的时候会节约大量的时间。默认情况下,堆内存快照会保存在JVM的启动目录下名为java_pid.hprof 的文件里(在这里就是JVM进程的进程号)。也可以通过设置-XX:HeapDumpPath=来改变默认的堆内存快照生成路径, Может быть относительным или абсолютным путем.
Цитировать:Настройка памяти параметров утилиты JVM Инструмент мониторинга настройки производительности JVM использование команды jstat
Гиталк загружается...