JVM 核心技术 —— 工具与 GC 策略
2023/5/2大约 10 分钟
JVM 核心技术 —— 工具与 GC 策略
1 JDK 内置命令行工具
jps -l 查看所有 Java 进程的进程号

jps -mlv
加上mlv参数之后可以打印更详细的信息(JVM 启动参数)

jinfo 进程号 打印 JVM 的配置信息
PS C:\Windows\system32> jinfo 8444
Attaching to process ID 8444, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.231-b11
Java System Properties:
java.runtime.name = Java(TM) SE Runtime Environment
java.vm.version = 25.231-b11
sun.boot.library.path = C:\Program Files\Java\jre1.8.0_231\bin
java.protocol.handler.pkgs = org.springframework.boot.loader
java.vendor.url = http://java.oracle.com/
java.vm.vendor = Oracle Corporation
path.separator = ;
java.rmi.server.randomIDs = true
file.encoding.pkg = sun.io
java.vm.name = Java HotSpot(TM) 64-Bit Server VM
sun.os.patch.level =
sun.java.launcher = SUN_STANDARD
user.script =
user.country = CN
user.dir = C:\Users\beam
java.vm.specification.name = Java Virtual Machine Specification
PID = 8444
java.runtime.version = 1.8.0_231-b11
java.awt.graphicsenv = sun.awt.Win32GraphicsEnvironment
os.arch = amd64
java.endorsed.dirs = C:\Program Files\Java\jre1.8.0_231\lib\endorsed
line.separator =
java.io.tmpdir = C:\Users\beam\AppData\Local\Temp\
java.vm.specification.vendor = Oracle Corporation
user.variant =
os.name = Windows 10
sun.jnu.encoding = GBK
java.library.path = C:\Program Files (x86)\Common Files\Oracle\Java\javapath;C:\Windows\Sun\Java\bin;C:\Windows\system32;C:\Windows;C:\Program Files (x86)\Common Files\Oracle\Java\javapath;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Windows\System32\OpenSSH\;C:\Program Files\Java\jdk1.8.0_231\bin;C:\Program Files\Java\jre1.8.0_231\bin;C:\Java\apache-maven-3.0.5\bin;C:\Users\beam\AppData\Local\Microsoft\WindowsApps;.
spring.beaninfo.ignore = true
java.specification.name = Java Platform API Specification
java.class.version = 52.0
sun.management.compiler = HotSpot 64-Bit Tiered Compilers
os.version = 10.0
user.home = C:\Users\beam
user.timezone = Asia/Shanghai
catalina.useNaming = false
java.awt.printerjob = sun.awt.windows.WPrinterJob
file.encoding = GBK
java.specification.version = 1.8
catalina.home = C:\Users\beam\AppData\Local\Temp\tomcat.8151514544322649683.8088
user.name = beam
java.class.path = .\gateway-server-0.0.1-SNAPSHOT.jar
java.vm.specification.version = 1.8
sun.arch.data.model = 64
sun.java.command = .\gateway-server-0.0.1-SNAPSHOT.jar
java.home = C:\Program Files\Java\jre1.8.0_231
user.language = zh
java.specification.vendor = Oracle Corporation
awt.toolkit = sun.awt.windows.WToolkit
java.vm.info = mixed mode
java.version = 1.8.0_231
java.ext.dirs = C:\Program Files\Java\jre1.8.0_231\lib\ext;C:\Windows\Sun\Java\lib\ext
sun.boot.class.path = C:\Program Files\Java\jre1.8.0_231\lib\resources.jar;C:\Program Files\Java\jre1.8.0_231\lib\rt.jar;C:\Program Files\Java\jre1.8.0_231\lib\sunrsasign.jar;C:\Program Files\Java\jre1.8.0_231\lib\jsse.jar;C:\Program Files\Java\jre1.8.0_231\lib\jce.jar;C:\Program Files\Java\jre1.8.0_231\lib\charsets.jar;C:\Program Files\Java\jre1.8.0_231\lib\jfr.jar;C:\Program Files\Java\jre1.8.0_231\classes
java.awt.headless = true
java.vendor = Oracle Corporation
sun.stderr.encoding = ms936
catalina.base = C:\Users\beam\AppData\Local\Temp\tomcat.8151514544322649683.8088
file.separator = \
java.vendor.url.bug = http://bugreport.sun.com/bugreport/
sun.io.unicode.encoding = UnicodeLittle
sun.cpu.endian = little
sun.stdout.encoding = ms936
sun.desktop = windows
sun.cpu.isalist = amd64
VM Flags:
Non-default VM flags: -XX:CICompilerCount=3 -XX:InitialHeapSize=1073741824 -XX:MaxHeapSize=1073741824 -XX:MaxNewSize=357564416 -XX:MinHeapDeltaBytes=524288 -XX:NewSize=357564416 -XX:OldSize=716177408 -XX:-UseAdaptiveSizePolicy -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseFastUnorderedTimeStamps -XX:-UseLargePagesIndividualAllocation -XX:+UseParallelGC
Command line: -Xmx1g -Xms1g -XX:-UseAdaptiveSizePolicy
jstat -gc 进程号 间隔时间(单位: 毫秒) 打印次数

-gcutil 显示百分比

-gcnew 只看young区

-gcold 只看old区

jmap -heap pid (JDK9 之后的 jmap 不支持 -heap 参数)
PS C:\Windows\system32> jmap -heap 8444
Attaching to process ID 8444, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.231-b11
using thread-local object allocation.
Parallel GC with 4 thread(s)
Heap Configuration:
MinHeapFreeRatio = 40
MaxHeapFreeRatio = 70
MaxHeapSize = 1073741824 (1024.0MB)
NewSize = 357564416 (341.0MB)
MaxNewSize = 357564416 (341.0MB)
OldSize = 716177408 (683.0MB)
NewRatio = 2
SurvivorRatio = 8
MetaspaceSize = 21807104 (20.796875MB)
CompressedClassSpaceSize = 1073741824 (1024.0MB)
MaxMetaspaceSize = 17592186044415 MB
G1HeapRegionSize = 0 (0.0MB)
Heap Usage:
PS Young Generation
Eden Space:
capacity = 268435456 (256.0MB)
used = 23466688 (22.37957763671875MB)
free = 244968768 (233.62042236328125MB)
8.742022514343262% used
From Space:
capacity = 44564480 (42.5MB)
used = 0 (0.0MB)
free = 44564480 (42.5MB)
0.0% used
To Space:
capacity = 44564480 (42.5MB)
used = 0 (0.0MB)
free = 44564480 (42.5MB)
0.0% used
PS Old Generation
capacity = 716177408 (683.0MB)
used = 18446112 (17.591583251953125MB)
free = 697731296 (665.4084167480469MB)
2.5756344439170022% used
16636 interned Strings occupying 2175776 bytes.
-histo pid 打印堆内存中的所有对象的信息

jstack [-l] pid 打印 JVM 线程栈的信息
PS C:\Windows\system32> jstack 8444
2023-04-26 00:01:01
Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.231-b11 mixed mode):
"RMI Scheduler(0)" #36 daemon prio=5 os_prio=0 tid=0x00000000203ab000 nid=0x1ec0 waiting on condition [0x000000002299e000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000000eab1a440> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.park(Unknown Source)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(Unknown Source)
at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(Unknown Source)
at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.getTask(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
"RMI TCP Accept-0" #34 daemon prio=5 os_prio=0 tid=0x00000000203ad800 nid=0x16e0 runnable [0x00000000016ee000]
java.lang.Thread.State: RUNNABLE
at java.net.DualStackPlainSocketImpl.accept0(Native Method)
at java.net.DualStackPlainSocketImpl.socketAccept(Unknown Source)
at java.net.AbstractPlainSocketImpl.accept(Unknown Source)
at java.net.PlainSocketImpl.accept(Unknown Source)
- locked <0x00000000eab208b8> (a java.net.SocksSocketImpl)
at java.net.ServerSocket.implAccept(Unknown Source)
at java.net.ServerSocket.accept(Unknown Source)
at sun.management.jmxremote.LocalRMIServerSocketFactory$1.accept(Unknown Source)
at sun.rmi.transport.tcp.TCPTransport$AcceptLoop.executeAcceptLoop(Unknown Source)
at sun.rmi.transport.tcp.TCPTransport$AcceptLoop.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
"DestroyJavaVM" #33 prio=5 os_prio=0 tid=0x00000000203aa800 nid=0x1dc4 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"http-nio-8088-AsyncTimeout" #31 daemon prio=5 os_prio=0 tid=0x00000000203a9800 nid=0x1748 waiting on condition [0x0000000023d9e000]
java.lang.Thread.State: TIMED_WAITING (sleeping)
at java.lang.Thread.sleep(Native Method)
at org.apache.coyote.AbstractProtocol$AsyncTimeout.run(AbstractProtocol.java:1143)
at java.lang.Thread.run(Unknown Source)
"http-nio-8088-Acceptor-0" #30 daemon prio=5 os_prio=0 tid=0x000000001cbb0000 nid=0x1128 runnable [0x0000000023c9f000]
java.lang.Thread.State: RUNNABLE
at sun.nio.ch.ServerSocketChannelImpl.accept0(Native Method)
at sun.nio.ch.ServerSocketChannelImpl.accept(Unknown Source)
at sun.nio.ch.ServerSocketChannelImpl.accept(Unknown Source)
- locked <0x00000000c0605a28> (a java.lang.Object)
at org.apache.tomcat.util.net.NioEndpoint$Acceptor.run(NioEndpoint.java:455)
at java.lang.Thread.run(Unknown Source)
"http-nio-8088-ClientPoller-1" #29 daemon prio=5 os_prio=0 tid=0x000000001cbae000 nid=0x808 runnable [0x0000000023b9f000]
java.lang.Thread.State: RUNNABLE
at sun.nio.ch.WindowsSelectorImpl$SubSelector.poll0(Native Method)
at sun.nio.ch.WindowsSelectorImpl$SubSelector.poll(Unknown Source)
at sun.nio.ch.WindowsSelectorImpl$SubSelector.access$400(Unknown Source)
at sun.nio.ch.WindowsSelectorImpl.doSelect(Unknown Source)
at sun.nio.ch.SelectorImpl.lockAndDoSelect(Unknown Source)
- locked <0x00000000c0606288> (a sun.nio.ch.Util$3)
- locked <0x00000000c0606278> (a java.util.Collections$UnmodifiableSet)
- locked <0x00000000c0606108> (a sun.nio.ch.WindowsSelectorImpl)
at sun.nio.ch.SelectorImpl.select(Unknown Source)
at org.apache.tomcat.util.net.NioEndpoint$Poller.run(NioEndpoint.java:798)
at java.lang.Thread.run(Unknown Source)
"http-nio-8088-ClientPoller-0" #28 daemon prio=5 os_prio=0 tid=0x000000001cbab000 nid=0x143c runnable [0x0000000023a9f000]
java.lang.Thread.State: RUNNABLE
at sun.nio.ch.WindowsSelectorImpl$SubSelector.poll0(Native Method)
at sun.nio.ch.WindowsSelectorImpl$SubSelector.poll(Unknown Source)
at sun.nio.ch.WindowsSelectorImpl$SubSelector.access$400(Unknown Source)
at sun.nio.ch.WindowsSelectorImpl.doSelect(Unknown Source)
at sun.nio.ch.SelectorImpl.lockAndDoSelect(Unknown Source)
- locked <0x00000000c0611ca0> (a sun.nio.ch.Util$3)
- locked <0x00000000c0611c90> (a java.util.Collections$UnmodifiableSet)
- locked <0x00000000c0611b20> (a sun.nio.ch.WindowsSelectorImpl)
at sun.nio.ch.SelectorImpl.select(Unknown Source)
at org.apache.tomcat.util.net.NioEndpoint$Poller.run(NioEndpoint.java:798)
at java.lang.Thread.run(Unknown Source)
"http-nio-8088-exec-10" #27 daemon prio=5 os_prio=0 tid=0x000000001cbab800 nid=0x1f7c waiting on condition [0x000000002399f000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000000c05ff7a8> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.park(Unknown Source)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(Unknown Source)
at java.util.concurrent.LinkedBlockingQueue.take(Unknown Source)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:103)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:31)
at java.util.concurrent.ThreadPoolExecutor.getTask(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Unknown Source)
"http-nio-8088-exec-9" #26 daemon prio=5 os_prio=0 tid=0x000000001cbac800 nid=0x2228 waiting on condition [0x000000002379f000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000000c05ff7a8> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.park(Unknown Source)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(Unknown Source)
at java.util.concurrent.LinkedBlockingQueue.take(Unknown Source)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:103)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:31)
at java.util.concurrent.ThreadPoolExecutor.getTask(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Unknown Source)
"http-nio-8088-exec-8" #25 daemon prio=5 os_prio=0 tid=0x000000001cbb1800 nid=0xa30 waiting on condition [0x000000002369e000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000000c05ff7a8> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.park(Unknown Source)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(Unknown Source)
at java.util.concurrent.LinkedBlockingQueue.take(Unknown Source)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:103)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:31)
at java.util.concurrent.ThreadPoolExecutor.getTask(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Unknown Source)
"http-nio-8088-exec-7" #24 daemon prio=5 os_prio=0 tid=0x000000001cbad000 nid=0xfec waiting on condition [0x000000002359f000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000000c05ff7a8> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.park(Unknown Source)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(Unknown Source)
at java.util.concurrent.LinkedBlockingQueue.take(Unknown Source)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:103)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:31)
at java.util.concurrent.ThreadPoolExecutor.getTask(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Unknown Source)
"http-nio-8088-exec-6" #23 daemon prio=5 os_prio=0 tid=0x000000001cbae800 nid=0x2294 waiting on condition [0x000000002349f000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000000c05ff7a8> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.park(Unknown Source)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(Unknown Source)
at java.util.concurrent.LinkedBlockingQueue.take(Unknown Source)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:103)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:31)
at java.util.concurrent.ThreadPoolExecutor.getTask(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Unknown Source)
"http-nio-8088-exec-5" #22 daemon prio=5 os_prio=0 tid=0x000000001cbaf800 nid=0x19fc waiting on condition [0x000000002339e000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000000c05ff7a8> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.park(Unknown Source)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(Unknown Source)
at java.util.concurrent.LinkedBlockingQueue.take(Unknown Source)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:103)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:31)
at java.util.concurrent.ThreadPoolExecutor.getTask(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Unknown Source)
"http-nio-8088-exec-4" #21 daemon prio=5 os_prio=0 tid=0x000000001cbb1000 nid=0x1a00 waiting on condition [0x000000002329f000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000000c05ff7a8> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.park(Unknown Source)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(Unknown Source)
at java.util.concurrent.LinkedBlockingQueue.take(Unknown Source)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:103)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:31)
at java.util.concurrent.ThreadPoolExecutor.getTask(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Unknown Source)
"http-nio-8088-exec-3" #20 daemon prio=5 os_prio=0 tid=0x0000000018d95800 nid=0x1420 waiting on condition [0x000000002319e000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000000c05ff7a8> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.park(Unknown Source)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(Unknown Source)
at java.util.concurrent.LinkedBlockingQueue.take(Unknown Source)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:103)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:31)
at java.util.concurrent.ThreadPoolExecutor.getTask(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Unknown Source)
"http-nio-8088-exec-2" #19 daemon prio=5 os_prio=0 tid=0x000000001abe0800 nid=0x1944 waiting on condition [0x000000002309f000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000000c05ff7a8> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.park(Unknown Source)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(Unknown Source)
at java.util.concurrent.LinkedBlockingQueue.take(Unknown Source)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:103)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:31)
at java.util.concurrent.ThreadPoolExecutor.getTask(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Unknown Source)
"http-nio-8088-exec-1" #18 daemon prio=5 os_prio=0 tid=0x000000001f63d800 nid=0x9b8 waiting on condition [0x0000000022f9e000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000000c05ff7a8> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.park(Unknown Source)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(Unknown Source)
at java.util.concurrent.LinkedBlockingQueue.take(Unknown Source)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:103)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:31)
at java.util.concurrent.ThreadPoolExecutor.getTask(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Unknown Source)
"NioBlockingSelector.BlockPoller-1" #17 daemon prio=5 os_prio=0 tid=0x0000000019642800 nid=0x17f0 runnable [0x0000000022e9f000]
java.lang.Thread.State: RUNNABLE
at sun.nio.ch.WindowsSelectorImpl$SubSelector.poll0(Native Method)
at sun.nio.ch.WindowsSelectorImpl$SubSelector.poll(Unknown Source)
at sun.nio.ch.WindowsSelectorImpl$SubSelector.access$400(Unknown Source)
at sun.nio.ch.WindowsSelectorImpl.doSelect(Unknown Source)
at sun.nio.ch.SelectorImpl.lockAndDoSelect(Unknown Source)
- locked <0x00000000c0601e48> (a sun.nio.ch.Util$3)
- locked <0x00000000c0601e38> (a java.util.Collections$UnmodifiableSet)
- locked <0x00000000c0601cc8> (a sun.nio.ch.WindowsSelectorImpl)
at sun.nio.ch.SelectorImpl.select(Unknown Source)
at org.apache.tomcat.util.net.NioBlockingSelector$BlockPoller.run(NioBlockingSelector.java:298)
"container-0" #16 prio=5 os_prio=0 tid=0x000000001d0bd800 nid=0x2150 waiting on condition [0x0000000022b9f000]
java.lang.Thread.State: TIMED_WAITING (sleeping)
at java.lang.Thread.sleep(Native Method)
at org.apache.catalina.core.StandardServer.await(StandardServer.java:427)
at org.springframework.boot.web.embedded.tomcat.TomcatWebServer$1.run(TomcatWebServer.java:182)
"ContainerBackgroundProcessor[StandardEngine[Tomcat]]" #15 daemon prio=5 os_prio=0 tid=0x000000001813b800 nid=0x144c waiting on condition [0x0000000022a9e000]
java.lang.Thread.State: TIMED_WAITING (sleeping)
at java.lang.Thread.sleep(Native Method)
at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.run(ContainerBase.java:1357)
at java.lang.Thread.run(Unknown Source)
"Service Thread" #9 daemon prio=9 os_prio=0 tid=0x00000000173fe800 nid=0x2070 runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"C1 CompilerThread2" #8 daemon prio=9 os_prio=2 tid=0x0000000017373800 nid=0x1c5c waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"C2 CompilerThread1" #7 daemon prio=9 os_prio=2 tid=0x0000000015d6c000 nid=0x16a4 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"C2 CompilerThread0" #6 daemon prio=9 os_prio=2 tid=0x0000000015d6a000 nid=0xd58 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"Attach Listener" #5 daemon prio=5 os_prio=2 tid=0x0000000015d68800 nid=0x1f70 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"Signal Dispatcher" #4 daemon prio=9 os_prio=2 tid=0x0000000015d67800 nid=0x12b0 runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"Finalizer" #3 daemon prio=8 os_prio=1 tid=0x0000000015cf9800 nid=0x17dc in Object.wait() [0x000000001705f000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x00000000c0049eb0> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(Unknown Source)
- locked <0x00000000c0049eb0> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(Unknown Source)
at java.lang.ref.Finalizer$FinalizerThread.run(Unknown Source)
"Reference Handler" #2 daemon prio=10 os_prio=2 tid=0x0000000003631000 nid=0x1a4c in Object.wait() [0x0000000016f5f000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x00000000c0056368> (a java.lang.ref.Reference$Lock)
at java.lang.Object.wait(Unknown Source)
at java.lang.ref.Reference.tryHandlePending(Unknown Source)
- locked <0x00000000c0056368> (a java.lang.ref.Reference$Lock)
at java.lang.ref.Reference$ReferenceHandler.run(Unknown Source)
"VM Thread" os_prio=2 tid=0x0000000015cd7800 nid=0x2028 runnable
"GC task thread#0 (ParallelGC)" os_prio=0 tid=0x0000000003556800 nid=0x1d64 runnable
"GC task thread#1 (ParallelGC)" os_prio=0 tid=0x0000000003558000 nid=0x1044 runnable
"GC task thread#2 (ParallelGC)" os_prio=0 tid=0x0000000003559800 nid=0xab8 runnable
"GC task thread#3 (ParallelGC)" os_prio=0 tid=0x000000000355c000 nid=0x1554 runnable
"VM Periodic Task Thread" os_prio=2 tid=0x000000001742d000 nid=0x1a5c waiting on condition
JNI global references: 939
"kill -3 +pid"是一种向进程发送信号的命令,其中的“+pid”是进程ID。这个命令的作用是向进程发送一个SIGQUIT信号,这个信号会让进程在退出前打印出当前的堆栈信息,以便于调试。
killl -9 pid 杀死一个进程
jcmd pid help 列出所有可用的 jcmd 命令
jcmd 3712
3712:
The following commands are available:
VM.unlock_commercial_features
JFR.configure
JFR.stop
JFR.start
JFR.dump
JFR.check
VM.native_memory
ManagementAgent.stop
ManagementAgent.start_local
ManagementAgent.start
VM.classloader_stats
GC.rotate_log
Thread.print
GC.class_stats
GC.class_histogram
GC.heap_dump
GC.finalizer_info
GC.heap_info
GC.run_finalization
GC.run
VM.uptime
VM.dynlibs
VM.flags
VM.system_properties
VM.command_line
VM.version
help
jrunscript 和 jjs: 像脚本语言一样编写 Java 代码。
2 JVM 图形化工具
jconsole

jvisualvm

JDK VisualGC —— IDEA 插件

jmc (商业软件)

3 GC
3.1 GC的背景与一般原理
引用计数
循环依赖
改进 -> 标记清除算法 (ParallelGC CMSGC)
STW(stop the world)
堆内存分代
分代假设:大部分新生对象很快无用;存活时间较长的对象,可能存活更长时间。
eden:s0: s1 = 8 : 1 : 1
可以作为GC Toots的对象
- 当前正在执行的方法里的局部变量和输入参数
- 活动线程
- 所有类的静态字段
- JNI引用
清除算法 old
复制算法(标记-复制算法)young
整理算法(标记-清楚-整理算法)old
串行( Serial )GC / ParNewGC
并行( Parallel )GC
并行/并发
--XX:+UseParallelGC
--XX:ParallelGCThreads=N 指定GC线程数,默认值为CPU核心数
java8 默认的GC算法是 ParallelGC
CMS GC (Concurrent Mark and Sweep Garbage Collector)
年轻代 并行 标记-复制算法
老年代 并发 (业务线程和GC线程并发执行)标记-清除算法
不对老年代进行整理,而是使用空列表来管理内存空间的回收
为什么要用并发呢? 让一次暂停的时间减少
CMS默认并发线程数为cpu核心数的1/4
G1 GC (Garbage-first GC)
堆不再划分年轻代和老年代,而是划分为多个可以存放对象的小块堆区
ZGC / Shenandoah GC
脱离场景谈性能都是耍流氓
默认最大堆内存
物理机内存 > 1g :: 1/4
young区 :: 1/3
old区 :: 2/3
物理机内存 < 1g :: 1/2