jmap
常用来查看jvm的内存信息,比如对象的实例个数以及对象占用的内存大小。
示例代码
public class JmapCode { public static void main(String[] args) throws InterruptedException { List<User> users = new ArrayList<>(); for (int i = 0; i < 1000; i++) { users.add(new User()); } Thread.sleep(Long.MAX_VALUE); } private static class User {} }
jps查看系统内java进程
➜ ~ jps 62304 Jps 59988 62278 JmapCode
jmap -histo <进程id> (查看jvm中对象的内存信息)
➜ ~ jmap -histo 62278 num #instances #bytes class name ---------------------------------------------- 1: 984 2823608 [I 2: 1755 1430760 [B 3: 5566 674256 [C 4: 3673 88152 java.lang.String 5: 654 74776 java.lang.Class 6: 766 56176 [Ljava.lang.Object; 7: 1000 16000 com.heoller.JmapCode$User ...(省略)
jmap -heap <进程id> (查看jvm内存信息)
Attaching to process ID 80244, please wait... Debugger attached successfully. Server compiler detected. JVM version is 10.0.1+10 using thread-local object allocation. Garbage-First (G1) GC with 4 thread(s) Heap Configuration: MinHeapFreeRatio = 40 MaxHeapFreeRatio = 70 MaxHeapSize = 4294967296 (4096.0MB) NewSize = 1363144 (1.2999954223632812MB) MaxNewSize = 2576351232 (2457.0MB) OldSize = 5452592 (5.1999969482421875MB) NewRatio = 2 SurvivorRatio = 8 MetaspaceSize = 21807104 (20.796875MB) CompressedClassSpaceSize = 1073741824 (1024.0MB) MaxMetaspaceSize = 17592186044415 MB G1HeapRegionSize = 1048576 (1.0MB) Heap Usage: G1 Heap: regions = 4096 capacity = 4294967296 (4096.0MB) used = 1048576 (1.0MB) free = 4293918720 (4095.0MB) 0.0244140625% used G1 Young Generation: Eden Space: regions = 1 capacity = 15728640 (15.0MB) used = 1048576 (1.0MB) free = 14680064 (14.0MB) 6.666666666666667% used Survivor Space: regions = 0 capacity = 0 (0.0MB) used = 0 (0.0MB) free = 0 (0.0MB) 0.0% used G1 Old Generation: regions = 0 capacity = 252706816 (241.0MB) used = 0 (0.0MB) free = 252706816 (241.0MB) 0.0% used 2036 interned Strings occupying 146048 bytes.
jmap -dump:format=b,file=jampCode.hprof <进程id> (生成dump文件,可以导进jvisualvm工具中查看)
通常是通过设置jvm启动参数来获取内存溢出时堆内存的dump文件
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=./oom.dump
public class OOMCode { /** * -Xms1M -Xmx1M -XX:+PrintGCDetails -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=./oom.dump * @param args */ public static void main(String[] args) { List<User> users = new ArrayList<>(); for (;;) { users.add(new User()); } } private static class User {} } # 运行结果 java.lang.OutOfMemoryError: Java heap space Dumping heap to ./oom.dump ... Heap dump file created [2328675 bytes in 0.024 secs] Exception in thread "main" java.lang.OutOfMemoryError: Java heap space at java.util.Arrays.copyOf(Arrays.java:3210) at java.util.Arrays.copyOf(Arrays.java:3181) at java.util.ArrayList.grow(ArrayList.java:265) at java.util.ArrayList.ensureExplicitCapacity(ArrayList.java:239) at java.util.ArrayList.ensureCapacityInternal(ArrayList.java:231) at java.util.ArrayList.add(ArrayList.java:462) at com.heoller.OOMCode.main(OOMCode.java:19)
jstack
示例代码
public class DeadLockCode { private static Object resourceA = new Object(); private static Object resourceB = new Object(); public static void main(String[] args) { new Thread(() -> { synchronized (resourceA) { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (resourceB) { System.out.println(); } } }).start(); new Thread(() -> { synchronized (resourceB) { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (resourceA) { System.out.println(); } } }).start(); } }
jstack <进程id> (检测出来死锁)
Found one Java-level deadlock: ============================= "Thread-1": waiting to lock monitor 0x00007fd78b811958 (object 0x000000076aeb55e8, a java.lang.Object), which is held by "Thread-0" "Thread-0": waiting to lock monitor 0x00007fd78b80ee08 (object 0x000000076aeb55f8, a java.lang.Object), which is held by "Thread-1" Java stack information for the threads listed above: =================================================== "Thread-1": at com.heoller.DeadLockCode.lambda$main$1(DeadLockCode.java:36) - waiting to lock <0x000000076aeb55e8> (a java.lang.Object) - locked <0x000000076aeb55f8> (a java.lang.Object) at com.heoller.DeadLockCode$$Lambda$2/127618319.run(Unknown Source) at java.lang.Thread.run(Thread.java:748) "Thread-0": at com.heoller.DeadLockCode.lambda$main$0(DeadLockCode.java:22) - waiting to lock <0x000000076aeb55f8> (a java.lang.Object) - locked <0x000000076aeb55e8> (a java.lang.Object) at com.heoller.DeadLockCode$$Lambda$1/940553268.run(Unknown Source) at java.lang.Thread.run(Thread.java:748) Found 1 deadlock.
同时jvisualvm也可以检测到死锁
jstack <pid> (查看CPU高的线程堆栈信息)</pid>
示例代码
public class CPUCode { public static void main(String[] args) { for(;;){} } }
- 定位java进程
[heoller@localhost ~]$ jps 4050 CPUCode 4090 Jps
- top -p 4050 后键入H,找到CPU最高的线程id,并换算成16进制
[heoller@localhost ~]$ top -p 4050 top - 23:19:58 up 6 min, 3 users, load average: 0.89, 0.62, 0.31 Tasks: 1 total, 0 running, 1 sleeping, 0 stopped, 0 zombie %Cpu(s): 10.4 us, 2.3 sy, 0.0 ni, 84.4 id, 2.8 wa, 0.0 hi, 0.0 si, 0.0 st KiB Mem : 1868688 total, 859704 free, 511500 used, 497484 buff/cache KiB Swap: 2097148 total, 2097148 free, 0 used. 1162248 avail Mem PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 4050 heoller 20 0 2888108 22968 10228 S 100.0 1.2 0:38.49 java ------------------键入H后,发现4051占用cpu最高------------------------ top - 23:20:05 up 6 min, 3 users, load average: 0.91, 0.63, 0.31 Threads: 15 total, 1 running, 14 sleeping, 0 stopped, 0 zombie %Cpu(s): 24.7 us, 0.0 sy, 0.0 ni, 75.3 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st KiB Mem : 1868688 total, 858928 free, 512376 used, 497384 buff/cache KiB Swap: 2097148 total, 2097148 free, 0 used. 1161504 avail Mem PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 4051 heoller 20 0 2888108 22968 10228 R 99.7 1.2 0:46.34 java 4064 heoller 20 0 2888108 22968 10228 S 0.3 1.2 0:00.03 java 4050 heoller 20 0 2888108 22968 10228 S 0.0 1.2 0:00.00 java 4052 heoller 20 0 2888108 22968 10228 S 0.0 1.2 0:00.00 java 4053 heoller 20 0 2888108 22968 10228 S 0.0 1.2 0:00.00 java 4054 heoller 20 0 2888108 22968 10228 S 0.0 1.2 0:00.00 java 4055 heoller 20 0 2888108 22968 10228 S 0.0 1.2 0:00.00 java 4056 heoller 20 0 2888108 22968 10228 S 0.0 1.2 0:00.00 java 4057 heoller 20 0 2888108 22968 10228 S 0.0 1.2 0:00.00 java 4058 heoller 20 0 2888108 22968 10228 S 0.0 1.2 0:00.00 java 4059 heoller 20 0 2888108 22968 10228 S 0.0 1.2 0:00.00 java 4060 heoller 20 0 2888108 22968 10228 S 0.0 1.2 0:00.00 java 4061 heoller 20 0 2888108 22968 10228 S 0.0 1.2 0:00.00 java 4062 heoller 20 0 2888108 22968 10228 S 0.0 1.2 0:00.00 java 4063 heoller 20 0 2888108 22968 10228 S 0.0 1.2 0:00.00 java
- jstack 4050|grep -A 5 <16进制数(字母小写)>
[heoller@localhost ~]$ jstack 4050|grep -A 5 fd3 "main" #1 prio=5 os_prio=0 tid=0x00007f200c009800 nid=0xfd3 runnable [0x00007f2013edf000] java.lang.Thread.State: RUNNABLE at CPUCode.main(CPUCode.java:3) "VM Thread" os_prio=0 tid=0x00007f200c078000 nid=0xfd8 runnable
jinfo
查看JVM启动参数
➜ ~ jinfo -flags 4251
查看Java系统参数
➜ ~ jinfo -sysprops 4954
jstat
动态查看堆内存大小的变化以及gc情况
➜ ~ jstat -gc 6508 1000 3 S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT(GC总耗时) 512.0 512.0 496.0 0.0 512.0 482.9 512.0 65.1 4864.0 3294.3 512.0 369.4 4 0.016 0 0.000 0.016 512.0 512.0 496.0 0.0 512.0 482.9 512.0 65.1 4864.0 3294.3 512.0 369.4 4 0.016 0 0.000 0.016 512.0 512.0 496.0 0.0 512.0 482.9 512.0 65.1 4864.0 3294.3 512.0 369.4 4 0.016 0 0.000 0.016